首页 > 系统 > Android > 正文

Android:解析XML的三种方式

2019-11-06 09:56:46
字体:
来源:转载
供稿:网友

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控件。代码如下:

 <TextView        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:textAppearance="?android:attr/textAppearanceLarge"        android:text="dfd"        android:id="@+id/tv_listview_one"        />    <TextView        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:textAppearance="?android:attr/textAppearanceLarge"        android:text="dfd"        android:id="@+id/tv_listview_two"        />    <TextView    android:layout_width="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<UserEntity> 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<UserEntity> 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 <node.getLength() ; i++) {                            Element element= (Element) node.item(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<UserEntity> list= (List<UserEntity>) 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<UserEntity> 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<UserEntity> 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<UserEntity> list= (List<UserEntity>) 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<UserEntity> 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<UserEntity> 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<UserEntity> list= (List<UserEntity>) o;            lists.addAll(list);            myadapter.notifyDataSetChanged();            pd.cancel();        }    }}5、需要增加网络权限。

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


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表