Android:解析XML的三种方式

1、首先,在布局文件中写一个Button控件和用来展示数据的ListView控件。

<Button  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:text="获取XML"  
    android:onClick="getdata"/>  

    <ListView  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:id="@+id/lv_main_data">  
    ListView>  

2、新建一个布局文件,用于listview展示数据,在这个布局文件中增加你要显示数据的TextView控件。代码如下:

"0dp"  
       android:layout_height="wrap_content"  
       android:layout_weight="1"  
       android:textAppearance="?android:attr/textAppearanceLarge"  
       android:text="dfd"  
       android:id="@+id/tv_listview_one"  

       />  
   "0dp"  
       android:layout_height="wrap_content"  
       android:layout_weight="1"  
       android:textAppearance="?android:attr/textAppearanceLarge"  
       android:text="dfd"  
       android:id="@+id/tv_listview_two"  

       />  
   "0dp"  
   android:layout_height="wrap_content"  
   android:layout_weight="1"  
   android:textAppearance="?android:attr/textAppearanceLarge"  
   android:text="dfd"  
   android:id="@+id/tv_listview_three"  

   />  

然后在MainActivity.java通过解析XML拿到数据。解析XML有三种方法,方法如下:

一、DOM解析器

  DOM(Document Object Model):是一种用于XML文档的对象模型,直接访问XML文档中所有部分。

 特点:解析速度快,一次性解析整个文档。加载大文件时候效率低。代码如下:
public class MainActivity extends AppCompatActivity {  
    private ListView lv_main_data;  
    private ProgressDialog pd;  
    private List lists = new ArrayList<>();  
    private MainActivity.myadapter myadapter;  
    String currentTag=null;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        lv_main_data = (ListView) findViewById(R.id.lv_main_data);//拿到listview的ID  
        myadapter = new myadapter();  
        lv_main_data.setAdapter(myadapter);  
        pd = new ProgressDialog(this);//动画加载中  
        pd.setMessage("locaging.....");  
    }  
    class myadapter extends BaseAdapter{  

        @Override  
        public int getCount() {  
            return lists.size();  
        }  
        @Override  
        public Object getItem(int position) {  
            return lists.get(position);  
        }  
        @Override  
        public long getItemId(int position) {  
            return position;  
        }  
        @Override  
        public View getView(int position, View convertView, ViewGroup parent) {  
              if (convertView==null){  
                  convertView= LayoutInflater.from(MainActivity.this).inflate(R.layout.dom_listview,null);  
                  DomActivity activity=new DomActivity();  
                  activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one);  
                  activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two);  
                  activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three);  
                  convertView.setTag(activity);  
              }  
            DomActivity domActivity= (DomActivity) convertView.getTag();  
            domActivity.uname.setText(lists.get(position).getUname());  
            domActivity.content.setText(lists.get(position).getContent());  
            domActivity.anthour.setText(lists.get(position).getAnthour());  
            return convertView;  
        }  
    }  
//获取xml数据  
    public void getdata(View view){  
      new mytask().execute();  
        pd.show();  
    }  
    //写一个继承AsyncTask,重写它的两个方法  
    // 1、获取网络数据:doInBackground  
    // 2、更新UI(数据):onPostExecute  
    class mytask extends AsyncTask{  

        private UserEntity userEntity;  
        private UserEntity userEntity1;  

        @Override  
        protected Object doInBackground(Object[] params) {  
            final List list = new ArrayList<>();  

            //获取网络数据:定义获取网络数据的路径  
            String path="http://192.168.43.143:8080/android/android_xml.xhtml";  
            try {  
                URL url=new URL(path);//实例化url:将获取网络数据的路径放到URL中。  
                HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();//获取连接的对象  
                httpURLConnection.setRequestMethod("GET");//设置请求的方式:1、get;2、post  
                httpURLConnection.setConnectTimeout(5000);//请求连接超时的时间  
                int code=httpURLConnection.getResponseCode(); //获取响应码的值  
                if (code==200){//判断:如果响应码等于200时,获取返回过来的是XML数据  
                    //通过流的形式读取  
                    InputStream inputStream=httpURLConnection.getInputStream();  
                    //测试:是否拿到值  
                    String str=null;  
                    //字符流  
//                    BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//把字符流转成字节流  
//                    while ((str=bufferedReader.readLine())!=null){  
//                        Log.i("test", "doInBackground: ");}  

                    // 解析XML:  1、DOM  2、SAX  3、PULL  

                    //  一、使用DOM解析  
                     try {  
                       //  1、使用DOM解析:特点:一次性解析整个文档  
                        //  (工厂模式就是单列模式 只要有newInstance就是单列模式)  
                        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();//创建工厂构建器,再拿DOM解析器  
                        DocumentBuilder builder=factory.newDocumentBuilder();//创建document的构建器,通过工厂拿到DOM解析器  
                        Document document=builder.parse(inputStream);//解析数流:通过解析器拿到数流  
                        //DOM解析的原理:1、获取文档的标签(跟标签)  
                        Element root=document.getDocumentElement();  
                        Log.i("test", "doInBackground: "+root.getTagName());  
                          //2、获取文档的标签下所有的子节点  
                        NodeList node=root.getElementsByTagName("fq");//获取节点  
                        for (int i = 0; i //3、获取节点下的属性  
                            String name=element.getAttribute("name");  
                            Log.i("test", "doInBackground: "+name);  
                            //4、获取子标签(拿标签的值)  
                            Element element1= (Element) element.getElementsByTagName("content").item(0);  
                            String content=element1.getTextContent();  
                            Element element2= (Element) element.getElementsByTagName("anthour").item(0);  
                            String anthour=element2.getTextContent();  
                            Log.i("test", "doInBackground: "+content+" ; "+anthour);  
                            UserEntity ue=new UserEntity(name,content,anthour);  
                            list.add(ue);  
                    }  
                    } catch (ParserConfigurationException e) {  
                        e.printStackTrace();  
                    } catch (SAXException e) {  
                        e.printStackTrace();  
                    }  

                }  
            } catch (MalformedURLException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            return list;  
        }  
        @Override//更新UI(数据)  
        protected void onPostExecute(Object o) {  
            super.onPostExecute(o);  
            List list= (List) o;  
            lists.addAll(list);  
            myadapter.notifyDataSetChanged();  
            pd.cancel();  
        }  
    }  
}  

二、SAX解析器

    SAX(Simple API XML):使用流的形式处理,是一种以基于事件(方法)为驱动的解析器。

   特点:边读边解析,解析速度快,占用内存少,同时sax解析提供了很多方法:开始、结束标签;开始、结束文档;文本的方法。代码如下:
public class MainActivity extends AppCompatActivity {  

    private ListView lv_main_data;  
    private ProgressDialog pd;  
    private List lists = new ArrayList<>();  
    private MainActivity.myadapter myadapter;  
    String currentTag=null;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        lv_main_data = (ListView) findViewById(R.id.lv_main_data);//拿到listview的ID  
        myadapter = new myadapter();  
        lv_main_data.setAdapter(myadapter);  
        pd = new ProgressDialog(this);//动画加载中  
        pd.setMessage("locaging.....");  
    }  
    class myadapter extends BaseAdapter{  

        @Override  
        public int getCount() {  
            return lists.size();  
        }  
        @Override  
        public Object getItem(int position) {  
            return lists.get(position);  
        }  
        @Override  
        public long getItemId(int position) {  
            return position;  
        }  
        @Override  
        public View getView(int position, View convertView, ViewGroup parent) {  
              if (convertView==null){  
                  convertView= LayoutInflater.from(MainActivity.this).inflate(R.layout.dom_listview,null);  
                  DomActivity activity=new DomActivity();  
                  activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one);  
                  activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two);  
                  activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three);  
                  convertView.setTag(activity);  
              }  
            DomActivity domActivity= (DomActivity) convertView.getTag();  
            domActivity.uname.setText(lists.get(position).getUname());  
            domActivity.content.setText(lists.get(position).getContent());  
            domActivity.anthour.setText(lists.get(position).getAnthour());  
            return convertView;  
        }  
    }  
//获取xml数据  
    public void getdata(View view){  
      new mytask().execute();  
        pd.show();  
    }  
    //写一个继承AsyncTask,重写它的两个方法  
    // 1、获取网络数据:doInBackground  
    // 2、更新UI(数据):onPostExecute  
    class mytask extends AsyncTask{  

        private UserEntity userEntity;  
        private UserEntity userEntity1;  

        @Override  
        protected Object doInBackground(Object[] params) {  
            final List list = new ArrayList<>();  

            //获取网络数据:定义获取网络数据的路径  
            String path="http://192.168.43.143:8080/android/android_xml.xhtml";  
            try {  
                URL url=new URL(path);//实例化url:将获取网络数据的路径放到URL中。  
                HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();//获取连接的对象  
                httpURLConnection.setRequestMethod("GET");//设置请求的方式:1、get;2、post  
                httpURLConnection.setConnectTimeout(5000);//请求连接超时的时间  
                int code=httpURLConnection.getResponseCode(); //获取响应码的值  
                if (code==200){//判断:如果响应码等于200时,获取返回过来的是XML数据  
                    //通过流的形式读取  
                    InputStream inputStream=httpURLConnection.getInputStream();  
                    //测试:是否拿到值  
                    String str=null;  

                    // 解析XML:  1、DOM  2、SAX  3、PULL  

                  //  二;使用sax解析  
                    try {  
                        //1、使用SAX解析:特点:边读边解析,基于事件(方法)驱动  
                        // sax解析提供了很多的方法:开始标签 开始文档的方法,结束标签 结束文档的方法 文本  
                        //创建sax工厂模式,通过工厂拿到解析器(和DOM解析一样)  
                        SAXParserFactory parserFactory=SAXParserFactory.newInstance();//创建sax工厂  
                        SAXParser saxParser=parserFactory.newSAXParser();//拿到解析器  
                        saxParser.parse(inputStream,new DefaultHandler(){//实现sax解析的方法  
                            //开始文档的方法  
                            @Override  
                            public void startDocument() throws SAXException {  
                                super.startDocument();  
                            }  
                            //结束文档的方法  
                            @Override  
                            public void endDocument() throws SAXException {  
                                super.endDocument();  
                            }  
                            //开始标签的方法  
                            @Override  
                            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {  
                                //1、拿到开始标签的名字:在DOM解析中,使用element拿到开始标签的名字。在sax解析中开始标签方法已经拿到了开始标签的名字  
                                super.startElement(uri, localName, qName, attributes);  
                                //2、拿到名字进行判断  
                                currentTag=localName;  
                                if ("fq".equals(localName)){//如果拿到的开始标签的名字是fq  
                                    //实列化对象  
                                    userEntity = new UserEntity();  
                                  //通过attributes拿属性的值.attributes多个属性的值  
                                    String name=attributes.getValue(0);  
                                    userEntity.setUname(name);//通过对象拿到标签属性的名字  
                                }  
                            }  
                            //结束标签的方法  
                            @Override  
                            public void endElement(String uri, String localName, String qName) throws SAXException {  
                                super.endElement(uri, localName, qName);  
                                currentTag=null;  
                                if ("fq".equals( localName)){  
                                    list.add(userEntity);  
                                }  
                            }  
                            //字符的方法  
                            @Override  
                            public void characters(char[] ch, int start, int length) throws SAXException {  
                                super.characters(ch, start, length);  
                                if ("content".equals(currentTag)){  
                                    String content=new String(ch, start, length);  
                                    userEntity.setContent(content);  
                                }else if ("anthour".equals(currentTag)){  
                                    String anthour=new String(ch, start, length);  
                                    userEntity.setAnthour(anthour);  
                                }  
                            }  
                        });  
                    } catch (ParserConfigurationException e) {  
                        e.printStackTrace();  
                    } catch (SAXException e) {  
                        e.printStackTrace();  
                    }  
                }  
            } catch (MalformedURLException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            return list;  
        }  
        @Override//更新UI(数据)  
        protected void onPostExecute(Object o) {  
            super.onPostExecute(o);  
            List list= (List) o;  
            lists.addAll(list);  
            myadapter.notifyDataSetChanged();  
            pd.cancel();  
        }  
    }}  

三、PULL解析器

  Pull解析器与SAX解析器性质类似,都是基于事件处理模式。不同的是用法:Pull解析器需要自己获取事件后做出相当于的操作,pull是用于Android,用于Java中需要导入pull解析依赖包。

特点:解析速度快、使用方便、效率高。代码如下:
public class MainActivity extends AppCompatActivity {  

    private ListView lv_main_data;  
    private ProgressDialog pd;  
    private List lists = new ArrayList<>();  
    private MainActivity.myadapter myadapter;  
    String currentTag=null;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        lv_main_data = (ListView) findViewById(R.id.lv_main_data);//拿到listview的ID  
        myadapter = new myadapter();//实列化方法  
        lv_main_data.setAdapter(myadapter);//给listview一个适配器  
        pd = new ProgressDialog(this);//动画加载中  
        pd.setMessage("locaging.....");  
    }  
    class myadapter extends BaseAdapter{//写一个类继承baseadapter,重写它的方法  

        @Override  
        public int getCount() {//获取集合数量  
            return lists.size();  
        }  
        @Override  
        public Object getItem(int position) {//获取当前集合  
            return lists.get(position);  
        }  
        @Override  
        public long getItemId(int position) {//获取当前位置  
            return position;  
        }  
        @Override  
        public View getView(int position, View convertView, ViewGroup parent) {  
              if (convertView==null){  
                  convertView= LayoutInflater.from(MainActivity.this).inflate(R.layout.dom_listview,null);  
                  DomActivity activity=new DomActivity();//实列化对象  
                  activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one);//将每个属性增加到每个控件ID中  
                  activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two);  
                  activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three);  
                  convertView.setTag(activity);//获取标签的属性  
              }  
            DomActivity domActivity= (DomActivity) convertView.getTag();//得到标签  
            domActivity.uname.setText(lists.get(position).getUname());//通过标签得到值  
            domActivity.content.setText(lists.get(position).getContent());  
            domActivity.anthour.setText(lists.get(position).getAnthour());  
            return convertView;  
        }  
    }  
//获取xml数据  
    public void getdata(View view){  
      new mytask().execute();  
        pd.show();//画面展示  
    }  
    //写一个继承AsyncTask,重写它的两个方法  
    // 1、获取网络数据:doInBackground  
    // 2、更新UI(数据):onPostExecute  
    class mytask extends AsyncTask{  

        private UserEntity userEntity;  
        private UserEntity userEntity1;  

        @Override  
        protected Object doInBackground(Object[] params) {  
            final List list = new ArrayList<>();  

            //获取网络数据:定义获取网络数据的路径  
            String path="http://192.168.43.143:8080/android/android_xml.xhtml";  
            try {  
                URL url=new URL(path);//实例化url:将获取网络数据的路径放到URL中。  
                HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();//获取连接的对象  
                httpURLConnection.setRequestMethod("GET");//设置请求的方式:1、get;2、post  
                httpURLConnection.setConnectTimeout(5000);//请求连接超时的时间  
                int code=httpURLConnection.getResponseCode(); //获取响应码的值  
                if (code==200){//判断:如果响应码等于200时,获取返回过来的是XML数据  
                    //通过流的形式读取  
                    InputStream inputStream=httpURLConnection.getInputStream();  
                    //测试:是否拿到值  
                    String str=null;  
                    //字符流  
//                    BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//把字符流转成字节流  
//                    while ((str=bufferedReader.readLine())!=null){  
//                        Log.i("test", "doInBackground: ");}  

                    // 解析XML:  1、DOM  2、SAX  3、PULL  

                  //  三、使用pull解析  
                    try {  
                        //01、pull解析:需要jar包,写一个类即可(XMLpullparser)--XMLpull解析器  
                        XmlPullParser pullParser= Xml.newPullParser();  
                        pullParser.setInput(inputStream,"utf-8");//获得数流形式以及编码格式  
                        //02、通过解析器拿到事件类型:开始标签,结束标签,开始文档,结束文档,文本  
                        int type=pullParser.getEventType();//type-- 开始文档  
                        //03、拿到开始文档进行判断  
                        while (type!=XmlPullParser.END_DOCUMENT){//如果开始文档不等于结束标签,type必须赋值,否则会出现死循环  
                            //type不断的改变,需要通过switch来判断  
                            switch (type){  
                                case XmlPullParser.START_TAG://如果是开始标签  
                                    //获取开始标签的名字  
                                   String startname= pullParser.getName();  
                                    if ("fq".equals(startname)){  
                                        //实列化对象  
                                        userEntity1 = new UserEntity();  
                                        String name=pullParser.getAttributeValue(0);//通过解析器得到值  
                                        userEntity1.setUname(name);  
                                    }else if ("content".equals(startname)){  
                                       String content= pullParser.nextText();//通过解析器拿到下一个文本内容  
                                        userEntity1.setContent(content);  
                                    }else if ("anthour".equals(startname)){  
                                        String anthour= pullParser.nextText();//通过解析器拿到下一个文本内容  
                                        userEntity1.setAnthour(anthour);  
                                    }  
                                    break;  
                                case  XmlPullParser.END_TAG://如果是结束标签  
                                    //获取结束标签  
                                   String sname= pullParser.getName();//通过pull解析器获取结束标签的名字  
                                    if ("fq".equals(sname)){  
                                        list.add(userEntity1);  
                                    }  
                                    break;  
                            }  
                            type=pullParser.next();//通过解析器拿到下一个的值  
                        }  
                    } catch (XmlPullParserException e) {  
                        e.printStackTrace();  
                    }  


                }  
            } catch (MalformedURLException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            return list;  
        }  
        @Override//更新UI(数据)  
        protected void onPostExecute(Object o) {  
            super.onPostExecute(o);  
            List list= (List) o;  
            lists.addAll(list);  
            myadapter.notifyDataSetChanged();  
            pd.cancel();  
        }  
    }  
}  

5、需要增加网络权限。

<uses-permission android:name="android.permission.INTERNET">uses-permission>  

你可能感兴趣的:(Android)