Androidxml的解析

今天我们来了解Androidd的xml解析方式,首先我们先在web端模拟一组数据,并将它发送到请求域当中去,代码如下:

public class FQAcgtion extends ActionSupport {  
    /** 
     *  
     */  
    private static final long serialVersionUID = 1L;  
  
    /** 
     * XAX 
     * @return   返回值 
     * @throws Exception 
     *  
     */  
    public String getXML() throws Exception {  
        // 获取数据  
        // 调用数据库查询数据,返回对象集合(....)  
        List<FQ> fqs = new ArrayList<FQ>();  
        for (int i = 1; i <= 100; i++) {  
            Calendar calendar = Calendar.getInstance();  
            int year = calendar.get(Calendar.YEAR);  
            int month = calendar.get(Calendar.MONTH);  
            int day = calendar.get(Calendar.DAY_OF_MONTH);  
            fqs.add(new FQ("小" + i, "今天心情很nice", year + "-" + month + "-" + day));  
        }  
  
        // 将对象集合存放到请求域中  
        //ServletActionContext.getRequest().setAttribute("fqs", fqs);  
  
        return "dataResult";  
    }  
      
      
      
} 
 

  然后我们再来一个XML(dataresult)返回我们模拟的数据(注意:上面不要留有空格,不然写空格,要不然我们这在Android端解析的时候会解析不到数据
<?xml version="1.0" encoding="UTF-8" ?><%@ page language="java" contentType="text/xml; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><fqs><c:forEach items="${fqs}" var="fq">  
            <fq name="${fq.name}">  
                <content>${fq.content}</content>  
                <time>${fq.time}</time>  
            </fq>  
    </c:forEach>  
    </fqs> 


       


   web端我们准备好了,现在我们开始在Android端解析数据,我们将数据解析到Android端,并用listview展示出来:如下图所示:




数据展示出来了:先在我们来解析xml,

XML解析数据有三种方式:

Activity_main.xml

<Button  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:text="获取XML"  
       android:onClick="getXML"  
       />  
  
   <ListView  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:id="@+id/lv_main_list"  
       >  
  
   </ListView> 
 
item_listview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/tv_item_listview_name" />

    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/tv_item_listview_content"  />

    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/tv_item_listview_time" />
</LinearLayout>

fq.class(里面放的是你的XML标签名,web端和Android端都需要有)
public class FQ {  
    private String name;  
    private String content;  
    private String time;  
    public FQ() {  
        super();  
    }  
    public FQ(String name, String content, String time) {  
        super();  
        this.name = name;  
        this.content = content;  
        this.time = time;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public String getContent() {  
        return content;  
    }  
    public void setContent(String content) {  
        this.content = content;  
    }  
    public String getTime() {  
        return time;  
    }  
    public void setTime(String time) {  
        this.time = time;  
    }  
}  


itemtag.class(listview优化)
public class ItemTag {  
    public TextView tv_name;  
    public TextView tv_content;  
    public TextView tv_time;  
}  




1.DOM解析


Android完全支持DOM 解析。利用DOM中的对象,可以对XML文档进行读取、搜索、修改、添加和删除等操作。

DOM的工作原理:使用DOM对XML文件进行操作时,首先要解析文件,将文件分为独立的元素、属性和注释等,然后以节点树的形式在内存中对XML文件进行表示,就可以通过节点树访问文档的内容,并根据需要修改文档——这就是DOM的工作原理。

DOM实现时首先为XML文档的解析定义一组接口,解析器读入整个文档,然后构造一个驻留内存的树结构,这样代码就可以使用DOM接口来操作整个树结构。 

由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。 当然,如果XML文件的内容比较小,采用DOM是可行的。

常用的DoM接口和类:

 Document:该接口定义分析并创建DOM文档的一系列方法,它是文档树的根,是操作DOM的基础。  

Element:该接口继承Node接口,提供了获取、修改XML元素名字和属性的方法。

Node:该接口提供处理并获取节点和子节点值的方法。

NodeList:提供获得节点个数和当前节点的方法。这样就可以迭代地访问各个节点。

DOMParser:该类是Apache的Xerces中的DOM解析器类,可直接解析XML文件。

下面是DOM的解析流程:

<p><span style="background-color: rgb(240, 240, 240);">public class MainActivity extends AppCompatActivity {</span></p><p></p>    private ProgressDialog progressDialog;  
    private ListView lv_main_list;  
  
  
    private List<FQ> lists=new ArrayList<>();  
    private MyAdapter myAdapter;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        lv_main_list = (ListView) findViewById(R.id.lv_main_list);  
  
  
        myAdapter = new MyAdapter();  
        lv_main_list.setAdapter(myAdapter);  
  
  
        progressDialog = new ProgressDialog(this);  
        progressDialog.setMessage("正在拼命loading中...");  
    }  
  
    class MyAdapter extends BaseAdapter{  
  
        @Override  
        public int getCount() {  
            return lists.size();  
        }  
  
        @Override  
        public Object getItem(int i) {  
            return lists.get(i);  
        }  
  
        @Override  
        public long getItemId(int i) {  
            return i;  
        }  
  
        @Override  
        public View getView(int i, View view, ViewGroup viewGroup) {  
  
            if(view==null){  
                view=LayoutInflater.from(MainActivity.this).inflate(R.layout.item_listview,null);  
  
                ItemTag itemTag=new ItemTag();  
  
                itemTag.tv_content= (TextView) view.findViewById(R.id.tv_item_listview_content);  
                itemTag.tv_name= (TextView) view.findViewById(R.id.tv_item_listview_name);  
                itemTag.tv_time= (TextView) view.findViewById(R.id.tv_item_listview_time);  
  
                view.setTag(itemTag);  
            }  
  
            ItemTag itemTag= (ItemTag) view.getTag();  
            itemTag.tv_name.setText(lists.get(i).getName());  
            itemTag.tv_content.setText(lists.get(i).getContent());  
            itemTag.tv_time.setText(lists.get(i).getTime());  
  
            return view;  
        }  
    }  
  
  
  
  
  
    public void getXML(View view){  
        new MyTask().execute();  
  
  
    }  
  
    class MyTask extends AsyncTask{  
  
        @Override  
        protected void onPreExecute() {  
            super.onPreExecute();  
            progressDialog.show();  
        }  
  
        @Override  
        protected Object doInBackground(Object[] objects) {  
  
            List<FQ> fqs=new ArrayList<>();  
  
            //获取网络数据  
            //01.定义获取网络的数据的路径  
            String path=getString(R.String.server_name)<span style="font-family:Arial, Helvetica, sans-serif;">+</span>"fqActiongetXML.action";  
            try {  
                //02.实例化Url  
                URL url=new URL(path);  
                //03.获取连接对象  
                HttpURLConnection conn= (HttpURLConnection) url.openConnection();  
                //04.设置请求方式  
                conn.setRequestMethod("GET");  
                //05.设置请求连接超时的时间  
                conn.setConnectTimeout(5000);  
  
                //06.获取响应码  
                int code=conn.getResponseCode();  
                if(code==200){  
                    //07.获取返回过来的数据(XML)  
                    InputStream is =conn.getInputStream();  
                    //08.测试(删除-注释)  
                    //缓冲字符流  
                    String str=null;  
//                    BufferedReader br=new BufferedReader(new InputStreamReader(is));  
//                    while((str=br.readLine())!=null){  
//                        Log.i("test",str);  
//                    }  
                    //09.解析XML  
                    //方式:DOM  SAX  PULL  
                    //09.1  使用DOM解析  
                    //设计模式:  
                    //单例模式(饿汉 懒汉)  
                    try {  
                        DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();  
                        DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder();  
                        Document document=documentBuilder.parse(is);  
                        //获取跟标签  
                        Element root=document.getDocumentElement();  
                        Log.i("test","跟标签:"+root.getTagName());  
  
                        //Node  Element  
                        NodeList nodeList=root.getElementsByTagName("fq");  
                        for (int i = 0; i <nodeList.getLength() ; i++) {  
                            Element element= (Element) nodeList.item(i);  
                            //获取属性name  
                            String name=element.getAttribute("name");  
  
                            //获取子标签<content><time>  
                            Element elementContent= (Element) element.getElementsByTagName("content").item(0);  
                            String content=elementContent.getTextContent();  
  
                            Element elementTime= (Element) element.getElementsByTagName("time").item(0);  
                            String time=elementTime.getTextContent();  
                            Log.i("test",name+" "+content+" "+time);  
  
                            FQ fq=new FQ(name,content,time);  
                            fqs.add(fq);  
                        }  
                    } catch (ParserConfigurationException e) {  
                        e.printStackTrace();  
                    } catch (SAXException e) {  
                        e.printStackTrace();  
                    }  
  
  
                }  
            } catch (MalformedURLException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            return fqs;  
        }  
  
        //更新UI  
        @Override  
        protected void onPostExecute(Object o) {  
            super.onPostExecute(o);  
  
            List<FQ> fqs= (List<FQ>) o;  
  
            lists.addAll(fqs);  
  
            myAdapter.notifyDataSetChanged();  
  
  
  
            progressDialog.cancel();  
  
  
        }  
    }  
  
  
  
}

2.SAX
SAX(Simple API for XML)解析器是一种基于事件的解析器,事件驱动的流式解析方式是,从文件的开始顺序解析到文档的结束,
不可暂停或倒退。它的核心是事件处理模式,

主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,

一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,

还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。  

  SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。

SAX的工作原理:SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)

开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,

由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

实现方法如下:

public class MainActivity extends AppCompatActivity {  
  
    private ProgressDialog progressDialog;  
    private ListView lv_main_list;  
    String currentTag=null;  
  
    private List<FQ> lists=new ArrayList<>();  
    private MyAdapter myAdapter;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        lv_main_list = (ListView) findViewById(R.id.lv_main_list);  
  
  
        myAdapter = new MyAdapter();  
        lv_main_list.setAdapter(myAdapter);  
  
  
        progressDialog = new ProgressDialog(this);  
        progressDialog.setMessage("正在拼命loading中...");  
    }  
  
    class MyAdapter extends BaseAdapter{  
  
        @Override  
        public int getCount() {  
            return lists.size();  
        }  
  
        @Override  
        public Object getItem(int i) {  
            return lists.get(i);  
        }  
  
        @Override  
        public long getItemId(int i) {  
            return i;  
        }  
  
        @Override  
        public View getView(int i, View view, ViewGroup viewGroup) {  
  
            if(view==null){  
                view=LayoutInflater.from(MainActivity.this).inflate(R.layout.item_listview,null);  
  
                ItemTag itemTag=new ItemTag();  
  
                itemTag.tv_content= (TextView) view.findViewById(R.id.tv_item_listview_content);  
                itemTag.tv_name= (TextView) view.findViewById(R.id.tv_item_listview_name);  
                itemTag.tv_time= (TextView) view.findViewById(R.id.tv_item_listview_time);  
  
                view.setTag(itemTag);  
            }  
  
            ItemTag itemTag= (ItemTag) view.getTag();  
            itemTag.tv_name.setText(lists.get(i).getName());  
            itemTag.tv_content.setText(lists.get(i).getContent());  
            itemTag.tv_time.setText(lists.get(i).getTime());  
  
            return view;  
        }  
    }  
  
  
  
  
  
    public void getXML(View view){  
        new MyTask().execute();  
  
  
    }  
  
    class MyTask extends AsyncTask{  
  
        private FQ fq;  
        private FQ fq1;  
  
        @Override  
        protected void onPreExecute() {  
            super.onPreExecute();  
            progressDialog.show();  
        }  
  
        @Override  
        protected Object doInBackground(Object[] objects) {  
  
            final List<FQ> fqs=new ArrayList<>();  
  
            //获取网络数据  
            //01.定义获取网络的数据的路径  
            String path=getString(R.string.server_name)+"fqActiongetXML.action";  
            try {  
                //02.实例化Url  
                URL url=new URL(path);  
                //03.获取连接对象  
                HttpURLConnection conn= (HttpURLConnection) url.openConnection();  
                //04.设置请求方式  
                conn.setRequestMethod("GET");  
                //05.设置请求连接超时的时间  
                conn.setConnectTimeout(5000);  
  
                //06.获取响应码  
                int code=conn.getResponseCode();  
                if(code==200){  
                    //07.获取返回过来的数据(XML)  
                    InputStream is =conn.getInputStream();  
                    //08.测试(删除-注释)  
                    //缓冲字符流  
                    String str=null;  
//                    BufferedReader br=new BufferedReader(new InputStreamReader(is));  
//                    while((str=br.readLine())!=null){  
//                        Log.i("test",str);  
//                    }  
                    //09.解析XML  
  
                    //02.使用SAX解析:特点:边读边解析  基于事件(方法)驱动方式  
                    //开始文档 开始标签  结束标签 结束文档  文本  
                    //<name>张三</name>  
//                    try {  
//                        SAXParserFactory saxParserFactory=SAXParserFactory.newInstance();  
//                        SAXParser saxParser=saxParserFactory.newSAXParser();  
//  
//                        saxParser.parse(is,new DefaultHandler(){  
//                            @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 {  
//                                super.startElement(uri, localName, qName, attributes);  
//                                currentTag=localName;  
//                                if("fq".equals(localName)){  
//                                    //实例化对象  
//                                    fq = new FQ();  
//                                    String name=attributes.getValue(0);  
//                                    fq.setName(name);  
//                                }  
//  
//                            }  
//  
//                            @Override  
//                            public void endElement(String uri, String localName, String qName) throws SAXException {  
//                                super.endElement(uri, localName, qName);  
//                                //细节:  
//                                currentTag=null;  
//                                if("fq".equals(localName)){  
//                                    fqs.add(fq);  
//                                }  
//                            }  
//  
//                            @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);  
//                                    fq.setContent(content);  
//                                } else if("time".equals(currentTag)){  
//                                    String time=new String(ch,start,length);  
//                                    fq.setTime(time);  
//                                }  
//                            }  
//                        });  
//                    } catch (ParserConfigurationException e) {  
//                        e.printStackTrace();  
//                    } catch (SAXException e) {  
//                        e.printStackTrace();  
//                    }  
  
                    
  
        //更新UI  
        @Override  
        protected void onPostExecute(Object o) {  
            super.onPostExecute(o);  
  
            List<FQ> fqs= (List<FQ>) o;  
  
            lists.addAll(fqs);  
  
            myAdapter.notifyDataSetChanged();  
  
            progressDialog.cancel();  
        }  
    }  
  
}  

3.PULL解析器: 

         
         

      Android并未提供对Java StAX API的支持。但是,Android附带了一个pull解析器,其工作方式类似于StAX。它允许用户的应用程序代码从解析器中获取事件,这与SAX解析器自动将事件推入处理程序相反。 

PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。

        读取到xml的声明返回 START_DOCUMENT;

读取到xml的结束返回 END_DOCUMENT ;

读取到xml的开始标签返回 START_TAG

读取到xml的结束标签返回 END_TAG

读取到xml的文本返回 TEXT

 PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器,Android官方推荐开发者们使用Pull解析技术。Pull解析技术是第三方开发的开源技术,它同样可以应用于JavaSE开发。

      PULL 的工作原理:XML pull提供了开始元素和结束元素。当某个元素开始时,我们可以调用parser.nextText从XML文档中提取所有字符数据。当解释到一个文档结束时,自动生成EndDocument事件。

      常用的XML pull的接口和类: 

XmlPullParser:XML pull解析器是一个在XMLPULL VlAP1中提供了定义解析功能的接口。

XmlSerializer:它是一个接口,定义了XML信息集的序列。

XmlPullParserFactory:这个类用于在XMPULL V1 API中创建XML Pull解析器。

XmlPullParserException:抛出单一的XML pull解析器相关的错误。

实现方法如下:
public class MainActivity extends AppCompatActivity {  
  
    private ProgressDialog progressDialog;  
    private ListView lv_main_list;  
    String currentTag=null;  
  
    private List<FQ> lists=new ArrayList<>();  
    private MyAdapter myAdapter;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        lv_main_list = (ListView) findViewById(R.id.lv_main_list);  
  
  
        myAdapter = new MyAdapter();  
        lv_main_list.setAdapter(myAdapter);  
  
  
        progressDialog = new ProgressDialog(this);  
        progressDialog.setMessage("正在拼命loading中...");  
    }  
  
    class MyAdapter extends BaseAdapter{  
  
        @Override  
        public int getCount() {  
            return lists.size();  
        }  
  
        @Override  
        public Object getItem(int i) {  
            return lists.get(i);  
        }  
  
        @Override  
        public long getItemId(int i) {  
            return i;  
        }  
  
        @Override  
        public View getView(int i, View view, ViewGroup viewGroup) {  
  
            if(view==null){  
                view=LayoutInflater.from(MainActivity.this).inflate(R.layout.item_listview,null);  
  
                ItemTag itemTag=new ItemTag();  
  
                itemTag.tv_content= (TextView) view.findViewById(R.id.tv_item_listview_content);  
                itemTag.tv_name= (TextView) view.findViewById(R.id.tv_item_listview_name);  
                itemTag.tv_time= (TextView) view.findViewById(R.id.tv_item_listview_time);  
  
                view.setTag(itemTag);  
            }  
  
            ItemTag itemTag= (ItemTag) view.getTag();  
            itemTag.tv_name.setText(lists.get(i).getName());  
            itemTag.tv_content.setText(lists.get(i).getContent());  
            itemTag.tv_time.setText(lists.get(i).getTime());  
  
            return view;  
        }  
    }  
  
  
  
  
  
    public void getXML(View view){  
        new MyTask().execute();  
  
  
    }  
  
    class MyTask extends AsyncTask{  
  
        private FQ fq;  
        private FQ fq1;  
  
        @Override  
        protected void onPreExecute() {  
            super.onPreExecute();  
            progressDialog.show();  
        }  
  
        @Override  
        protected Object doInBackground(Object[] objects) {  
  
            final List<FQ> fqs=new ArrayList<>();  
  
            //获取网络数据  
            //01.定义获取网络的数据的路径  
            String path=getString(R.string.server_name)+"fqActiongetXML.action";  
            try {  
                //02.实例化Url  
                URL url=new URL(path);  
                //03.获取连接对象  
                HttpURLConnection conn= (HttpURLConnection) url.openConnection();  
                //04.设置请求方式  
                conn.setRequestMethod("GET");  
                //05.设置请求连接超时的时间  
                conn.setConnectTimeout(5000);  
  
                //06.获取响应码  
                int code=conn.getResponseCode();  
                if(code==200){  
                    //07.获取返回过来的数据(XML)  
                    InputStream is =conn.getInputStream();  
                    //08.测试(删除-注释)  
                    //缓冲字符流  
                    String str=null;  
//                    BufferedReader br=new BufferedReader(new InputStreamReader(is));  
//                    while((str=br.readLine())!=null){  
//                        Log.i("test",str);  
//                    }  
                    //09.解析XML  
                    try {  
                        //03.使用PULL解析  
                        XmlPullParser pullParser=Xml.newPullParser();  
                        pullParser.setInput(is,"UTF-8");  
                        int type=pullParser.getEventType();  
  
                        while(type!=XmlPullParser.END_DOCUMENT){  
                            switch (type) {  
                                case XmlPullParser.START_TAG:  
                                    //获取开始标签的名字  
                                    String startTagName=pullParser.getName();  
                                    if("fq".equals(startTagName)){  
                                        fq1 = new FQ();  
                                        String name=pullParser.getAttributeValue(0);  
                                        fq1.setName(name);  
                                    }else if("content".equals(startTagName)){  
                                       String content= pullParser.nextText();  
                                        fq1.setContent(content);  
                                    }else if("time".equals(startTagName)){  
                                        String time= pullParser.nextText();  
                                        fq1.setTime(time);  
                                    }  
                                    break;  
                                case XmlPullParser.END_TAG:  
                                    //获取结束标签的名字  
                                    String endTagName=pullParser.getName();  
                                    if("fq".equals(endTagName)){  
                                        fqs.add(fq1);  
                                    }  
                                    break;  
                            }  
                            type=pullParser.next();  
                        }  
                    } catch (XmlPullParserException e) {  
                        e.printStackTrace();  
                    }  
  
  
                }  
            } catch (MalformedURLException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            return fqs;  
        }  
  
        //更新UI  
        @Override  
        protected void onPostExecute(Object o) {  
            super.onPostExecute(o);  
  
            List<FQ> fqs= (List<FQ>) o;  
  
            lists.addAll(fqs);  
  
            myAdapter.notifyDataSetChanged();  
  
            progressDialog.cancel();  
        }  
    }  
  
}  










  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值