xml dom 解析器然后使用列表视图显示结果

Posted

技术标签:

【中文标题】xml dom 解析器然后使用列表视图显示结果【英文标题】:xml dom parser then display the result with list-view 【发布时间】:2016-08-03 01:12:44 【问题描述】:

我有 web 服务,它有方法返回 xml 字符串给我我想解析这个 xml 然后用列表视图显示它。

主要活动

    public class MainActivity extends ListActivity 
    // All static variables
   format=xml";
    // XML node keys
    static final String KEY_ITEM = "Roomtype"; // parent node
    static final String KEY_ID = "IDRoom";
    static final String KEY_NAME = "Code";
    static final String KEY_COST = "Normbed";
    static final String KEY_DESC = "Maxbed";
    static final String KEY_categroy = "Category";
    static final String KEY_order = "Order";

    ProgressBar pg;
    String spin1;
    String spin2;
    String spin3;
    String displayText;
    TextView tv;
    ListView lv;
    int day, month, year;
    ArrayList<HashMap<String, String>> menuItems;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Spinner spinner1 = (Spinner) findViewById(R.id.spinner1);
        Spinner spinner2 = (Spinner) findViewById(R.id.spinner2);
        Spinner spinner3 = (Spinner) findViewById(R.id.spinner3);
        pg = (ProgressBar) findViewById(R.id.progressBar1);
        spin1 =  spinner1.getSelectedItem().toString();
        spin2 =  spinner2.getSelectedItem().toString();
        spin3 =  spinner3.getSelectedItem().toString();


        //Search
        Button btn_search=(Button)findViewById(R.id.btn_search);
        btn_search.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                //Create instance for AsyncCallWS
                AsyncCallWS task = new AsyncCallWS();
                //Call execute
                AsyncTask<String, Void, Void> xx=task.execute();

            
        );
    
private void parsexml(String xmlresult)

    ListView myList=(ListView)findViewById(android.R.id.list);

    menuItems = new ArrayList<HashMap<String, String>>();

    XmlParser parser = new XmlParser();
    String xml = null; // getting XML
    try 
        xml = parser.getXmlFormUrl(xmlresult);
     catch (IOException e) 
        e.printStackTrace();
    
    Document doc = parser.getDomElement(xml); // getting DOM element
    NodeList nl = doc.getElementsByTagName(KEY_ITEM);

    // looping through all item nodes <item>
    for (int i = 0; i < nl.getLength(); i++) 
        // creating new HashMap
        HashMap<String, String> map = new HashMap<String, String>();
        Element e = (Element) nl.item(i);
        // adding each child node to HashMap key => value
        map.put(KEY_ID,  parser.getValue(e, KEY_ID));
        map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
        map.put(KEY_COST, "Rs." + parser.getValue(e, KEY_COST));
        map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
        map.put(KEY_DESC, parser.getValue(e, KEY_categroy));
        map.put(KEY_DESC, parser.getValue(e, KEY_order));
        // adding HashList to ArrayList
        menuItems.add(map);
    
    // Adding menuItems to ListView
    ListAdapter adapter = new SimpleAdapter(this, menuItems,
            R.layout.list_item,
            new String[]  KEY_NAME, KEY_DESC, KEY_COST,KEY_categroy,KEY_order , new int[] 
            R.id.name, R.id.desciption, R.id.cost,R.id.categroy,R.id.order );

    setListAdapter(adapter);



    private class AsyncCallWS extends AsyncTask<String, Void, Void> 
        private Exception exception;
        @Override
        protected Void doInBackground(String... params) 
            try 
                //Invoke webservice
                displayText = WebService.invokeHelloWorldWS(spin2, spin3, spin1, "search_availability");
                parsexml(displayText);

            catch (Exception e) 
                this.exception = e;
                return null;
            
            return null;
        

        @Override
        protected void onPostExecute(Void result) 

            //Make ProgressBar invisible
            pg.setVisibility(View.INVISIBLE);
        

        @Override
        protected void onPreExecute() 
            //Make ProgressBar invisible
            pg.setVisibility(View.VISIBLE);
        

        @Override
        protected void onProgressUpdate(Void... values) 
        

    


XmlParser 类

public class XmlParser 

    String result;
    public String getXmlFormUrl(String link) throws IOException 
        URL url=new URL(link.toString());
        HttpURLConnection UrlConnection= (HttpURLConnection) url.openConnection();
        int status=UrlConnection.getResponseCode();
        if(status==200)
            InputStream inputStream=UrlConnection.getInputStream();
            BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"UTF8"));
            StringBuilder stringBuilder= new StringBuilder();
            String line;
            while ((line=bufferedReader.readLine())!=null)
                stringBuilder.append((line+"\n"));
            
            result=stringBuilder.toString();
            inputStream.close();
        
        return  result;
    
    public Document getDomElement(String xml)
        Document doc = null;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try 

            DocumentBuilder db = dbf.newDocumentBuilder();

            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xml));
            doc = db.parse(is);

         catch (ParserConfigurationException e) 
            Log.e("Error: ", e.getMessage());
            return null;
         catch (SAXException e) 
            Log.e("Error: ", e.getMessage());
            return null;
         catch (IOException e) 
            Log.e("Error: ", e.getMessage());
            return null;
        
        // return DOM
        return doc;
    
    public String getValue(Element item, String str) 
        NodeList n = item.getElementsByTagName(str);
        return this.getElementValue(n.item(0));
    

    public final String getElementValue( Node elem ) 
        Node child;
        if( elem != null)
            if (elem.hasChildNodes())
                for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() )
                    if( child.getNodeType() == Node.TEXT_NODE  )
                        return child.getNodeValue();
                    
                
            
        
        return "";
    

当我点击搜索按钮时,这是 xml 文件主文件,结果将显示。 MainActivity.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    android:paddingBottom="16dp"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_
        android:layout_
        android:orientation="horizontal">
        <TextView
            android:id="@+id/tv_arrival"
            android:layout_
            android:layout_
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:text="Arrival Date"/>

        <Button
            android:id="@+id/btn_arrival"
            android:layout_
            android:layout_
            android:layout_alignParentRight="true"
            android:text="Set"/>
    </RelativeLayout>
    <RelativeLayout
        android:layout_
        android:layout_>
        <TextView
            android:id="@+id/tv_departure"
            android:layout_
            android:layout_
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:text="Departure Date"/>

        <Button
            android:id="@+id/btn_departure"
            android:layout_
            android:layout_
            android:layout_alignParentRight="true"
            android:text="Set"/>
    </RelativeLayout>
    <RelativeLayout
        android:layout_
        android:layout_>
        <TextView
            android:layout_
            android:layout_
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:text="Persons"/>
        <Spinner
            android:id="@+id/spinner2"
            android:layout_
            android:layout_
            android:layout_alignParentRight="true"
            android:background="@android:drawable/btn_dropdown"
            android:spinnerMode="dropdown"
            android:entries="@array/array_person"/>
    </RelativeLayout>
    <RelativeLayout
        android:layout_
        android:layout_>
        <TextView
            android:layout_
            android:layout_
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:text="child"/>
        <Spinner
            android:id="@+id/spinner3"
            android:layout_
            android:layout_
            android:layout_alignParentRight="true"
            android:background="@android:drawable/btn_dropdown"
            android:spinnerMode="dropdown"
            android:entries="@array/array_child"/>
    </RelativeLayout>
    <RelativeLayout
        android:layout_
        android:layout_>
        <TextView
            android:layout_
            android:layout_
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:text="Rooms"/>
        <Spinner
            android:id="@+id/spinner1"
            android:layout_
            android:layout_
            android:layout_alignParentRight="true"
            android:background="@android:drawable/btn_dropdown"
            android:spinnerMode="dropdown"
            android:drawSelectorOnTop="true"
            android:entries="@array/array_rooms"
            />
    </RelativeLayout>


    <RelativeLayout
        android:layout_
        android:layout_>
        <Button
            android:id="@+id/btn_login"
            android:layout_
            android:layout_
            android:layout_alignParentRight="true"
            android:text="Login"/>
        <Button
            android:id="@+id/btn_search"
            android:layout_
            android:layout_
            android:layout_alignParentLeft="true"
            android:text="Search"/>
    </RelativeLayout>
    <RelativeLayout
        android:layout_
        android:layout_>

        <ListView
            android:layout_
            android:layout_
            android:id="@android:id/list"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="73dp" />
    </RelativeLayout>
    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_
        android:layout_
        android:layout_gravity="center_horizontal"
        android:visibility="invisible"
        />
</LinearLayout>

List_items.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="horizontal">
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_
        android:layout_
        android:orientation="vertical">
        <!-- Name Label -->
        <TextView
            android:id="@+id/name"
            android:layout_
            android:layout_
            android:textColor="#dc6800"
            android:textSize="16sp"
            android:textStyle="bold"
            android:paddingTop="6dip"
            android:paddingBottom="2dip" />
        <!-- Description label -->
        <TextView
            android:id="@+id/desciption"
            android:layout_
            android:layout_
            android:textColor="#acacac"
            android:paddingBottom="2dip">
        </TextView>
        <!-- Linear layout for cost and price Cost: Rs.100 -->
        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_
            android:layout_
            android:orientation="horizontal">
            <!-- Cost Label -->
            <TextView
                android:layout_
                android:layout_
                android:textColor="#5d5d5d"
                android:gravity="left"
                android:textStyle="bold"
                android:text="Cost: " >
            </TextView>
            <!-- Price Label -->
            <TextView
                android:id="@+id/cost"
                android:layout_
                android:layout_
                android:textColor="#acacac"
                android:textStyle="bold"
                android:gravity="left">
            </TextView>
            <TextView
                android:id="@+id/categroy"
                android:layout_
                android:layout_
                android:textColor="#acacac"
                android:textStyle="bold"
                android:gravity="left">
            </TextView>
            <TextView
                android:id="@+id/order"
                android:layout_
                android:layout_
                android:textColor="#acacac"
                android:textStyle="bold"
                android:gravity="left">
            </TextView>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

【问题讨论】:

我想你只需要做 parsexml(displayText);在设置适配器后的 postExecuted 和 notifyDataSetChanged() 中 OK 我把 parsexml(displayText);在 postExecuted 和 DataSetChanged() 中设置适配器 notifyDataSetChanged() 在 setListAdapter(adapter) 之后; 你的意思是我在 setListAdapter(adapter) 之后创建 notifyDataSetChanged() 方法 在调用此函数的适配器中通知数据集更改:ad​​apter.notifyDataSetChanged(); 【参考方案1】:

您正尝试使用来自WebService.invokeHelloWorldWS(spin2, spin3, spin1, "search_availability"); 的 xml 结果再次获取 xml 结果,更改您的代码以改为解析 xml。

例子:

private void parsexml(String xmlresult)

    ListView myList=(ListView)findViewById(android.R.id.list);

    menuItems = new ArrayList<HashMap<String, String>>();

    XmlParser parser = new XmlParser();
    Document doc = parser.getDomElement(xmlresult); // getting DOM element
    NodeList nl = doc.getElementsByTagName(KEY_ITEM);

    // looping through all item nodes <item>
    for (int i = 0; i < nl.getLength(); i++) 
        // creating new HashMap
        HashMap<String, String> map = new HashMap<String, String>();
        Element e = (Element) nl.item(i);
        // adding each child node to HashMap key => value
        map.put(KEY_ID,  parser.getValue(e, KEY_ID));
        map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
        map.put(KEY_COST, "Rs." + parser.getValue(e, KEY_COST));
        map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
        map.put(KEY_DESC, parser.getValue(e, KEY_categroy));
        map.put(KEY_DESC, parser.getValue(e, KEY_order));
        // adding HashList to ArrayList
        menuItems.add(map);
    
    // Adding menuItems to ListView
    ListAdapter adapter = new SimpleAdapter(this, menuItems,
            R.layout.list_item,
            new String[]  KEY_NAME, KEY_DESC, KEY_COST,KEY_categroy,KEY_order , new int[] 
            R.id.name, R.id.desciption, R.id.cost,R.id.categroy,R.id.order );

    myList.setListAdapter(adapter);
    ((BaseAdapter)adapter).notifyDataSetChanged();


不要忘记在onPostExecute()notifyDataSetChanged()setListAdapter(adapter) 之后执行parsexml()

【讨论】:

好的,我添加了所有的东西,除了 adapter.notifyDataSetChanged();当我添加它时,它用红色标记我没有找到它 setListAdapter(adapter); adapter.notifyDataSetChanged();//红色 是parsexml的最后一行 没有别的了 adapter.notifyDataSetChanged();此行无法导入此方法 按照我的改变去做:myList.setListAdapter(adapter); ((BaseAdapter)适配器).notifyDataSetChanged(); 是的,但我想问你我想显示这个 xml,如果你不喜欢,我不知道如何使用 listview 属性可以提供帮助

以上是关于xml dom 解析器然后使用列表视图显示结果的主要内容,如果未能解决你的问题,请参考以下文章

使用 Javascript DOM 解析器从 WMS GetCapabilities 请求的 XML response.data 中提取层列表

JAVA之DOM和SAX解析器

笔记:XML-解析文档-DOM

使用 DOM 解析器在 Java 中解析具有 2 个默认命名空间的 XML

xml文件解析(使用解析器)

使用 dom4j 解析XML