Android XML解析

解析XML有三种方式:Dom、SAX、Pull

其中pull解析器运行方式与SAX类似。

我们首先认识pull解析器:http://developer.android.com/intl/zh-cn/reference/org/xmlpull/v1/XmlPullParser.html

Th following event types are seen by next()

START_TAG
An XML start tag was read.
TEXT
Text content was read; the text content can be retrieved using the getText() method. (when in validating mode next() will not report ignorable whitespace, use nextToken() instead)
END_TAG
An end tag was read
END_DOCUMENT
No more events are available

1.解析
获取解析器: Xml.newPullParser()
设置输入流: parser.setInput(InputStream, String)
获取当前事件类型: parser.getEventType(), 
获取下一个事件类型: parser.next()
获取标签名: parser.getName()
获取属性值: parser.getAttributeValue(int)、getAttributeValue(null,"id")
获取下一个文本: parser.nextText()
2.生成
获取解析器:
设置输出流:
开始文档:
结束文档:
开启标签:
结束标签:
设置属性:
设置文本:

下面我们用一个实例来看看:

在src下面新建presons.xml

 1 <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>

 2 <persons>

 3     <person id="1">

 4         <name>范冰冰</name>

 5         <age>31</age>

 6     </person>

 7     <person id="2">

 8         <name>林志玲</name>

 9         <age>38</age>

10     </person>

11     <person id="3">

12         <name>杨幂</name>

13         <age>26</age>

14     </person>

15 </persons>
View Code

然后在包中创建Person.java、PersonService.java、PersonTest.java

 1 public class PersonService {

 2     

 3     public List<Person> loadPersons(InputStream in) throws Exception {

 4         XmlPullParser parser = Xml.newPullParser();        // 获取解析器

 5         parser.setInput(in, "UTF-8");                    // 设置输入流, 指定码表

 6             

 7         ArrayList<Person> persons = new ArrayList<Person>();

 8         Person p = null;

 9         

10         // 最初type赋值为第一个事件, 只要不是文档结束就循环, 每次循环后解析下一个事件

11         for (int type = parser.getEventType(); type != XmlPullParser.END_DOCUMENT; type = parser.next()) {

12             if (type == XmlPullParser.START_TAG) {                // 如果遇到了标签开始事件

13                 if (parser.getName().equals("person")) {        // 如果标签名为"person"

14                     p = new Person();                            // 创建对象

15                     String id = parser.getAttributeValue(0);    // 获取第一个属性的属性值

16                     p.setId(Integer.parseInt(id));                // 转为int, 设置id

17                     persons.add(p);                                // 装入集合

18                 } else if (parser.getName().equals("name")) {    // 如果标签名为"name"

19                     String name = parser.nextText();            // 获取下一个文本

20                     p.setName(name);                            // 设置name

21                 } else if (parser.getName().equals("age")) {    // 如果标签名为"age"

22                     String age = parser.nextText();                // 获取下一个文本

23                     p.setAge(Integer.parseInt(age));            // 设置age

24                 }

25             } 

26         }

27         

28         return persons;

29     }

30 

31     public void savePersons(List<Person> persons, OutputStream out) throws IOException {

32         XmlSerializer serializer = Xml.newSerializer();        // 获取序列化工具

33         serializer.setOutput(out, "UTF-8");                    // 设置输出流, 指定码表

34         

35         serializer.startDocument("UTF-8", true);    // 开始文档

36         serializer.startTag(null, "persons");        // 开始标签

37         

38         for (Person p : persons) {

39             serializer.startTag(null, "person");

40             serializer.attribute(null, "id", p.getId().toString());        // 设置属性

41             

42             serializer.startTag(null, "name");

43             serializer.text(p.getName());            // 设置文本

44             serializer.endTag(null, "name");

45             

46             serializer.startTag(null, "age");

47             serializer.text(p.getAge().toString());

48             serializer.endTag(null, "age");

49             

50             serializer.endTag(null, "person");

51         }

52         

53         serializer.endTag(null, "persons");            // 结束标签

54         serializer.endDocument();                    // 结束文档

55     }

56 

57 }
View Code
 1 public class PersonTest extends AndroidTestCase {

 2 

 3     public void testLoad() throws Exception {

 4         PersonService service = new PersonService();

 5         InputStream in = PersonTest.class.getClassLoader().getResourceAsStream("persons.xml");

 6         List<Person> persons = service.loadPersons(in);

 7         for (Person p : persons) 

 8             System.out.println(p);

 9         

10         Person p = new Person(4, "张红", 18);

11         persons.add(p);

12         service.savePersons(persons, new FileOutputStream("/mnt/sdcard/persons.xml"));

13     }

14     

15 }
View Code
 1 public class Person {

 2     private Integer id;

 3     private String name;

 4     private Integer age;

 5 

 6     public Person() {

 7         super();

 8     }

 9 

10     public Person(Integer id, String name, Integer age) {

11         super();

12         this.id = id;

13         this.name = name;

14         this.age = age;

15     }

16 

17     public Integer getId() {

18         return id;

19     }

20 

21     public void setId(Integer id) {

22         this.id = id;

23     }

24 

25     public String getName() {

26         return name;

27     }

28 

29     public void setName(String name) {

30         this.name = name;

31     }

32 

33     public Integer getAge() {

34         return age;

35     }

36 

37     public void setAge(Integer age) {

38         this.age = age;

39     }

40 

41     @Override

42     public String toString() {

43         return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";

44     }

45 

46 }
View Code

然后运行程序,可在日志中看到解析的数据。

(最好添加一个日志信息的过滤器,专门查看System.out输出的信息)

 

以上部分只讲解了PULL解析,下面我们用这三种解析方式解析同一个XML文件(在代码中注释讲解)。

需要我们解析的XML内容如下:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>

<persons>

    <person id="1">

        <name>saber</name>

        <age>20</age>

    </person>

    <person id="2">

        <name>Archer</name>

        <age>21</age>

    </person>

    <person id="3">

        <name>Lancer</name>

        <age>26</age>

    </person>

</persons>

其存放在名为“assets”的文件夹下,取名为“test”。

整个程序代码文件如下:

Android XML解析

接下来,实现一个实体类,该类的属性应与XML文件对应,名为“Person.java”,其实现如下:

package com.topcsa.entity;



public class Person {

    private Integer id;

    private String name;

    private Integer age;



    public Person() {

        super();

    }



    public Person(Integer id, String name, Integer age) {

        super();

        this.id = id;

        this.name = name;

        this.age = age;

    }



    public Integer getId() {

        return id;

    }



    public void setId(Integer id) {

        this.id = id;

    }



    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }



    public Integer getAge() {

        return age;

    }



    public void setAge(Integer age) {

        this.age = age;

    }



    @Override

    public String toString() {

        return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";

    }



}

 

名为“XmlUtils.java”的文件实现如下:

package com.topcsa.utils;



import java.io.IOException;

import java.io.InputStream;

import java.util.ArrayList;

import java.util.List;



import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;



import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.NodeList;

import org.xml.sax.Attributes;

import org.xml.sax.InputSource;

import org.xml.sax.SAXException;

import org.xml.sax.XMLReader;

import org.xml.sax.helpers.DefaultHandler;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserException;



import com.topcsa.entity.Person;



import android.content.Context;

import android.util.Xml;



public class XmlUtils {



    public List<Person> XmlPullParse(Context con) {

        InputStream inputStream = null;

        ArrayList<Person> persons = new ArrayList<Person>();

        Person p = null;

        XmlPullParser parser = Xml.newPullParser(); // 获取解析器

        // 得到文件流,并设置编码方式

        try {

            inputStream = con.getResources().getAssets().open("test.xml");

            parser.setInput(inputStream, "UTF-8"); // 设置输入流, 指定码表

            // 最初type赋值为第一个事件, 只要不是文档结束就循环, 每次循环后解析下一个事件

            for (int type = parser.getEventType(); type != XmlPullParser.END_DOCUMENT; type = parser

                    .next()) {

                if (type == XmlPullParser.START_TAG) { // 如果遇到了标签开始事件

                    if (parser.getName().equals("person")) { // 如果标签名为"person"

                        p = new Person(); // 创建对象

                        String id = parser.getAttributeValue(0); // 获取第一个属性的属性值

                        p.setId(Integer.parseInt(id)); // 转为int, 设置id

                        persons.add(p); // 装入集合

                    } else if (parser.getName().equals("name")) { // 如果标签名为"name"

                        String name = parser.nextText(); // 获取下一个文本

                        p.setName(name); // 设置name

                    } else if (parser.getName().equals("age")) { // 如果标签名为"age"

                        String age = parser.nextText(); // 获取下一个文本

                        p.setAge(Integer.parseInt(age)); // 设置age

                    }

                    

                }

            }

        } catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        } catch (XmlPullParserException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }



        return persons;



    }



    public List<Person> XmlSaxParse(Context con) {



        List<Person> persons = null;

        // 建立Sax解析工厂

        SAXParserFactory factory = SAXParserFactory.newInstance();

        try {

            // 取得SaxParser对象

            SAXParser parser = factory.newSAXParser();

            // 获取事件源

            XMLReader xmlReader = parser.getXMLReader();

            // 设置sax解析器

            PersonSaxHandler handler = new PersonSaxHandler();

            xmlReader.setContentHandler(handler);

            // 解析xml文档

            xmlReader.parse(new InputSource(con.getAssets().open("test.xml")));

            persons = handler.getPersons();

        } catch (ParserConfigurationException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        } catch (SAXException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }



        return persons;



    }



    public List<Person> XmlDomParse(Context con) {

        List<Person> persons = new ArrayList<Person>();

        DocumentBuilderFactory factory = null;

        DocumentBuilder builder = null;

        Document document = null;

        InputStream inputStream = null;

        // 建立DocumentBuilderFactory对象,用于取得DocumentBuilder

        factory = DocumentBuilderFactory.newInstance();

        try {

            // 找到XML文档

            inputStream = con.getResources().getAssets().open("test.xml");

            // 通过DocumentBuilderFactory取得DocumentBuilder

            builder = factory.newDocumentBuilder();

            // 读取指定路径的XML文件

            document = builder.parse(inputStream);

            // 找到根Element

            Element root = document.getDocumentElement();

            NodeList nodes = root.getElementsByTagName("person");

            // 遍历所有根节点下的子节点,persons下的所有person

            Person person = null;

            for (int i = 0; i < nodes.getLength(); i++) {

                person = new Person();

                // 获取person元素节点

                Element personElement = (Element) (nodes.item(i));

                // 获取person中id属性值

                person.setId(Integer.parseInt(personElement.getAttribute("id")));

                // 获取person下name标签

                Element personName = (Element) personElement

                        .getElementsByTagName("name").item(0);

                person.setName(personName.getFirstChild().getNodeValue());

                // 获取person下age标签

                Element personAge = (Element) personElement

                        .getElementsByTagName("age").item(0);

                person.setAge(Integer.parseInt(personAge.getFirstChild()

                        .getNodeValue()));

                persons.add(person);

            }

        } catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        } catch (ParserConfigurationException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        } catch (SAXException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        return persons;



    }

    

    //Sax解析方式需要的类

    class PersonSaxHandler extends DefaultHandler {



        private List<Person> list = null;

        private String elementName = null;

        private Person person = null;



        @Override

        public void startDocument() throws SAXException {// 文档开始,实例化集合

            // TODO Auto-generated method stub

            this.list = new ArrayList<Person>();

        }



        // 元素开始

        @Override

        public void startElement(String uri, String localName, String qName,

                Attributes attributes) throws SAXException {

            localName = localName.toLowerCase().trim();

            // 如果读取的是person标签开始,则实例化Person

            if (localName.equals("person")) {

                this.person = new Person();

                // 导航到person开始节点后

                this.person.setId(Integer.parseInt(attributes.getValue("id")));

            }

            // 保存元素名称

            this.elementName = localName;

        }



        @Override

        public void characters(char[] ch, int start, int length)// 获取元素类容

                throws SAXException {

            if (this.elementName != null) {// 表示有元素

                String data = new String(ch, start, length);// 取得文字信息

                if (this.elementName.equals("name")) {

                    this.person.setName(data);

                } else if (this.elementName.equals("age")) {

                    this.person.setAge(Integer.parseInt(data));

                }

            }

        }



        // 元素结尾

        @Override

        public void endElement(String uri, String localName, String qName)

                throws SAXException {

            if (localName.equals("person")) {// 判断元素标记是"person"

                this.list.add(this.person);// 向集合中保存数据

                this.person = null;// 清空对象

            }

            this.elementName = null;// 青空元素标记

        }



        public List<Person> getPersons() {// 取得全部集合

            return this.list;



        }

    }



}

 

MainActivity的布局文件activity_main.xml实现如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >



    <Button

        android:id="@+id/btn_dom"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Dom解析" />



    <Button

        android:id="@+id/btn_sax"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Sax解析" />



    <Button

        android:id="@+id/btn_pull"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Pull解析" />



    <TextView

        android:id="@+id/tv"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />



</LinearLayout>
View Code

MainActivity的实现如下:

package com.topcsa.zhj_test;



import java.util.ArrayList;

import java.util.List;



import android.app.Activity;

import android.os.Bundle;

import android.support.v4.widget.DrawerLayout;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;



import com.topcsa.entity.Person;

import com.topcsa.utils.XmlUtils;



public class MainActivity extends Activity {

    private XmlUtils xmlutils;

    private List<Person> persons;

    private StringBuffer sb;

    private TextView tv;



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Button btnDom = (Button) findViewById(R.id.btn_dom);

        Button btnSax = (Button) findViewById(R.id.btn_sax);

        Button btnPull = (Button) findViewById(R.id.btn_pull);

        xmlutils = new XmlUtils();

        persons = new ArrayList<Person>();

        sb = new StringBuffer();



        btnDom.setOnClickListener(new OnClickListener() {



            @Override

            public void onClick(View arg0) {

                sb.append("Dom解析:");

                persons = xmlutils.XmlDomParse(MainActivity.this);

                for (int i = 0; i < persons.size(); i++) {

                    Person person = persons.get(i);

                    sb.append("姓名:" + person.getName() + ",id:"

                            + person.getId() + ",年龄:" + person.getAge() + ";    ");



                }

                tv.setText(sb.toString());

            }

        });

        btnSax.setOnClickListener(new OnClickListener() {



            @Override

            public void onClick(View arg0) {

                sb.append("Sax解析:");

                persons = xmlutils.XmlSaxParse(MainActivity.this);

                for (int i = 0; i < persons.size(); i++) {

                    Person person = persons.get(i);

                    sb.append("姓名:" + person.getName() + ",id:"

                            + person.getId() + ",年龄:" + person.getAge() + ";    ");



                }

                tv.setText(sb.toString());



            }

        });

        btnPull.setOnClickListener(new OnClickListener() {



            @Override

            public void onClick(View arg0) {

                sb.append("Pull解析:");

                persons = xmlutils.XmlPullParse(MainActivity.this);

                if (persons != null) {

                    System.out.println("不为空"+persons.size());

                } else {

                    System.out.println("为空");

                }

                for (int i = 0; i < persons.size(); i++) {

                    Person person = persons.get(i);

                    sb.append("姓名:" + person.getName() + ",id:"

                            + person.getId() + ",年龄:" + person.getAge() + ";    ");



                }

                tv.setText(sb.toString());



            }

        });



        tv = (TextView) findViewById(R.id.tv);



    }



}
View Code

 

最后程序运行如下:

Android XML解析

你可能感兴趣的:(android)