zoukankan      html  css  js  c++  java
  • 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”。

    整个程序代码文件如下:

    接下来,实现一个实体类,该类的属性应与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

    最后程序运行如下:

    作者:af74776
    文章出处:http://www.cnblogs.com/scetopcsa/
    欢迎关注微信公众号:yilu_yiyou(一路一游),一个不仅仅是代码的世界!
    如果文中有什么错误,欢迎指出。以免更多的人被误导。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    02-高阶函数 map filter sorted
    01-切片的赋值操作
    学习资料记录
    django_初级学习(1)
    git配置使用
    openpyxl操作表格(2)
    openpyxl模块操作excell表格(1)
    精简语法
    MySQL常见面试题
    02-图片转字符画
  • 原文地址:https://www.cnblogs.com/scetopcsa/p/3643487.html
Copyright © 2011-2022 走看看