XML解析

  1 import java.io.File;
  2 import java.io.FileInputStream;
  3 import java.io.IOException;
  4 import java.io.InputStream;
  5 import java.util.ArrayList;
  6 import java.util.List;
  7 
  8 import javax.xml.*;
  9 import javax.xml.parsers.DocumentBuilder;
 10 import javax.xml.parsers.DocumentBuilderFactory;
 11 import javax.xml.parsers.SAXParser;
 12 import javax.xml.parsers.SAXParserFactory;
 13 import javax.xml.transform.sax.SAXTransformerFactory;
 14 
 15 import org.w3c.dom.Document;
 16 import org.w3c.dom.NamedNodeMap;
 17 import org.w3c.dom.Node;
 18 import org.w3c.dom.NodeList;
 19 import org.xml.sax.Attributes;
 20 import org.xml.sax.SAXException;
 21 import org.xml.sax.helpers.DefaultHandler;
 22 /*XML文件
 23 <?xml version="1.0" encoding="UTF-8"?>
 24 <users>
 25     <user id="01">   id为属性 name为元素
 26         <name>张三</name>
 27         <age>15</age>
 28     </user>
 29      <user id="02">
 30         <name>李四</name>
 31         <age>15</age>
 32     </user>
 33 </users>
 34 以下三种解析方法中的User为自定义类,用来接收对象的值
 35 XML是一个以文本来描述数据的文档
 36 SAX表现较好,这要依赖于它特定的解析方式。一个SAX 检测即将到来的XML流,但并
 37 没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。
 38 DOM的优点,由于树在内存中是持久的,因此可以修改后更新。它还可以在任何时候在树
 39 中上下导航,API使用起来也较简单。
 40  */
 41 public class XMLParser {
 42     private String id;
 43     private String name;
 44     private String age;
 45     public static void main(String[] args) throws Exception {
 46         List<User> list=new XMLParser().XMLParser_SAX();
 47         System.out.println(list);
 48     }
 49     //XML解析方法之:DOM:将整个文档树在内存中,便于操作,支持删除,修改,重新排列等多种功能,但占内存
 50     public List<User> parserDom() throws Exception{
 51         ArrayList<User> list=new ArrayList<User>();//存放解析的数据
 52         User user=null;
 53         DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();//创建一个文件建筑工厂
 54         DocumentBuilder builder= factory.newDocumentBuilder();//创建一个建筑者
 55         InputStream is=new FileInputStream("E:\\学习文件\\Android文件\\eclipse代码\\work_space\\XML_parser\\src\\users.xml");
 56         Document parse = builder.parse(is);//创建一个解析器, 也可以传入一个流对象,从而利用转换流指定编码格式
 57         NodeList nodes = parse.getElementsByTagName("user");//解析user
 58         for(int i=0;i<nodes.getLength();i++){
 59             NamedNodeMap map = nodes.item(i).getAttributes();//获取装属性的集合(如id)
 60             user=new User();//存放用户信息
 61             for(int j=0;j<map.getLength();j++){//当属性有多个值的时候就可以这样解析
 62                 if(map.item(j).getNodeName().equals("id")){//获得属性的名字
 63                     id=map.item(j).getNodeValue();//获得属性的值
 64                     user.setId(id);
 65                 }
 66             }
 67             NodeList childNodes = nodes.item(i).getChildNodes();//获取子节点(装元素的集合)
 68             for(int k=0;k<childNodes.getLength();k++){
 69                 String nodeName = childNodes.item(k).getNodeName();
 70                 if(nodeName.equals("name")){
 71                     name=childNodes.item(k).getTextContent();//获取元素值
 72                     user.setName(name);
 73                 }else if(nodeName.equals("age")){
 74                     age=childNodes.item(k).getTextContent();
 75                     user.setAge(age);
 76                 }
 77             }
 78             list.add(user);
 79             user=null;//避免数据存放出错
 80         }
 81         return list;
 82     }
 83     //XML解析方法之:SAX:不用事先调入整个文档,占用资源少 ,一行行解析的
 84     public List<User> XMLParser_SAX() throws Exception{
 85         SAXParserFactory factory = SAXParserFactory.newInstance();
 86         SAXParser parser = factory.newSAXParser();
 87         InputStream is=new FileInputStream("E:\\学习文件\\Android文件\\eclipse代码\\work_space\\XML_parser\\src\\users.xml");
 88         UserHandler handler=new UserHandler();
 89         parser.parse(is, handler);
 90         List<User> list = handler.getUser();
 91         return list;
 92     }
 93     class UserHandler extends DefaultHandler{//SAX解析方式的需要
 94         ArrayList<User> list;//存放解析的数据
 95         User user=null;
 96         String flag;//用来标记解析的是哪个属性或元素
 97         public void startDocument() throws SAXException {
 98             System.out.println("开始解析");
 99         }
100         public void endDocument() throws SAXException {
101             System.out.println("解析结束");
102         }
103         public void startElement(String uri, String localName, String qName,
104                 Attributes attributes) throws SAXException {
105         //解析这样的语句:<users> <user> <name> <age>的时候回调此方法
106             if(qName.equals("users")){
107                 list=new ArrayList<User>();
108             }else if(qName.equals("user")){
109                 user=new User();//没解析一个用户就创建一个对象
110                 user.setId(attributes.getValue("id"));//获取属性id的值
111             }else{
112                 flag=qName;//得到解析的是哪个元素
113             }
114         }
115         //解析这样的语句:</users> </user>  </name>的时候回调此方法
116         public void endElement(String uri, String localName, String qName)
117                 throws SAXException {
118             if(qName.equals("user")){
119                 list.add(user);//解析完一个就添加且清除
120                 user=null;
121             }
122         }
123         //解析元素和属性的时候回调此方法
124         public void characters(char[] ch, int start, int length)
125                 throws SAXException {
126             if(flag!=null){//在解析属性的时候为空
127                 if(flag.equals("name")){
128                     user.setName(new String(ch,start,length));
129                 }else if(flag.equals("age")){
130                     user.setAge(new String(ch,start,length));
131                 }
132             }
133             flag=null;//没有这句,数据就会出错,很多空格
134         }
135         public List<User> getUser(){//提供一方法返回解析数据
136             return list;
137         }
138     }
139 }
140     //XML解析第三种方法:PUll需要下载这个包:org.xmlpull.v1

解析图解

 

 

 

说明解析到哪条执行相对应的方法   下图数字代码对应的编码

 

存放数据的User类

 1 public class User {
 2     private String id;
 3     private String name;
 4     private String age;
 5     public String getId() {
 6         return id;
 7     }
 8     public void setId(String id) {
 9         this.id = id;
10     }
11     public String getName() {
12         return name;
13     }
14     public void setName(String name) {
15         this.name = name;
16     }
17     public String getAge() {
18         return age;
19     }
20     public void setAge(String age) {
21         this.age = age;
22     }
23     @Override
24     public String toString() {
25         return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
26     }
27     
28 }

 PULL解析XML文件例子:需要的包名:kxml2-2.2.2.jar

解析的XML文件:

<?xml version="1.0" encoding="gbk"?>
<students>
    <student id="1001">
        <name>夏志明</name>
        <age>18</age>
        <sex></sex>
        <books>
            <book>
                <name>十万个为什么</name>
                <author>匿名</author>
                <price>100</price>
            </book>
            <book>
                <name>平凡的世界</name>
                <author>路遥</author>
                <price>200</price>
            </book>
            <book>
                <name>人生</name>
                <author>路遥</author>
                <price>100</price>
            </book>
        </books>
    </student>
    <student id="1002">
        <name>方高</name>
        <age>18</age>
        <sex></sex>
        <books>
             <book>
                <name>java开发大全</name>
                <author>李刚</author>
                <price>100</price>
            </book>
             <book>
                <name>人生</name>
                <author>路遥</author>
                <price>100</price>
            </book>
        </books>       
    </student>    
</students>

java代码:

package com.mobiletrain.pull02;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

/*
 * pull解析注意:
parser.nextText()代表下一个内容
parser.next()代表下一个节点
得到标签的属性名称 (如:student id="1001"  id就为属性)
String att = parser.getAttributeName(0);
得到标签的属性的值
String value = parser.getAttributeValue(0);
 */
public class Test {
    public static void main(String[] args) {
        try {
            // 1,创建解析器工厂对象
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            // 2,由解析器工厂对象创建解析器对象
            XmlPullParser parser = factory.newPullParser();
            // 3,设置数据源
            parser.setInput(new FileReader("students.xml"));
            // 4,得到事件码
            int code = parser.getEventType();
            List<Student> students = null;
            Student student = null;
            List<Book> books = null;
            Book book = null;
            String nowTag = null;
            while (code != 1) {
                String name = parser.getName();// 得到节点的名称
                switch (code) {
                case 2:
                    if ("students".equals(name)) {
                        students = new ArrayList<Student>();
                    } else if ("student".equals(name)) {
                        student = new Student();
                        nowTag = "学生";
                        // 得到Student的属性名称
                        // String att = parser.getAttributeName(0);
                        // 得到Student标签的属性的值
                        String value = parser.getAttributeValue(0);
                        student.setId(Integer.parseInt(value));
                    } else if ("name".equals(name) && "学生".equals(nowTag)) {
                        student.setName(parser.nextText());
                    } else if ("age".equals(name)) {
                        student.setAge(Integer.parseInt(parser.nextText()));
                    } else if ("sex".equals(name)) {
                        student.setSex(parser.nextText());
                    } else if ("books".equals(name)) {
                        books = new ArrayList<Book>();
                    } else if ("book".equals(name)) {
                        book = new Book();
                        nowTag = "书";

                    } else if ("name".equals(name) && "书".equals(nowTag)) {
                        book.setName(parser.nextText());
                    } else if ("author".equals(name)) {
                        book.setAuthor(parser.nextText());
                    } else if ("price".equals(name)) {
                        book.setPrice(Integer.parseInt(parser.nextText()));
                    }

                    break;
                case 3:
                    if ("book".equals(name)) {
                        books.add(book);
                    } else if ("books".equals(name)) {
                        student.setList(books);
                    } else if ("student".equals(name)) {
                        students.add(student);
                    }

                    break;
                default:
                    break;
                }

                // 解析下一个节点
                code = parser.next();// 得到下一个节点的事件码

            }

            for (Student student2 : students) {
                System.out.println(student2);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

存放数据的类:

package com.mobiletrain.pull02;

import java.util.List;

public class Student {
    private int id;
    private String name;
    private String sex;
    private int age;
    private List<Book> list;

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setList(List<Book> list) {
        this.list = list;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", list=" + list + "]\n";
    }

}

 

注意点:

1.xml属性要打双引号

2.当解析的文件源是字符串而不是一个文件的时候(当使用网络下载数据保存到字符串上时:)

String xml = HttpUtils.getXMLByInternet("http://weather.xcyh.org/xml/7");//自定义的下载工具  将xml数据下载到字符串中
// 解析xml数据
// 创建解析器工厂对象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 2,创建解析器对象
XmlPullParser parser = factory.newPullParser();
// 3,设置数据源
// StringReader 是Reader的子类
// StringReader 的数据源是String类型的字符串
parser.setInput(new StringReader(xml));         //当这里是数据源是文件的时候就是  new FileReader("xml文件路径");
// 4,得到事件码
int code = parser.getEventType();

 

posted @ 2016-04-16 13:58  ts-android  阅读(746)  评论(0编辑  收藏  举报