XML的解析方法详解

来源:互联网 发布:五线谱转吉他谱软件 编辑:程序博客网 时间:2024/05/16 09:10

XML 概述:

可扩展性标记语言  eXtensible Markup Language

XML用于描述数据

应用场合:1.持久化存储数据;2.数据交换;3.数据配置















Android中,常见的XML解析器分别为SAX解析器、DOM解析器和PULL解析器,下面,我将一一向大家详细介绍。
SAX解析器:
SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。
SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。
DOM解析器:
DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。
由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。
PULL解析器:
PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器。

三种解析方式区别:
    (1)SAX解析器的优点是解析速度快,占用内存少
        DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。
        PULL解析器的运行方式和SAX类似,都是基于事件的模式。PULL解析器小巧轻便,解析速度快,简单易用。
    (2)DOM,它是生成一个树,有了树以后你搜索、查找都可以做。
         SAX和PULL是基于流的,就是解析器从头到尾解析一遍xml文件,解析完了以后你不过想再查找重新解析。

SAX和PULL的区别:
    (1)sax的原理是解析器解析过程中通过回调把tag/value值等传给你,你可以比较、操作。
 而pull的原理是它只告诉你一个tag开始或者结束了,至于tag/value的值是什么需要你自己去向parser问,所以叫做pull,而sax看起来          是push给你的。
(2)如果在一个XML文档中我们只需要前面一部分数据,但是使用SAX方式或DOM方式会对整个文档进行解析,尽管XML文档中后面的大部分数据我们其实都不需要解析,因此这样实际上就浪费了处理资源。使用PULL方式正合适。
        Pull解析器和SAX解析器虽有区别但也有相似性。他们的区别为:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。也就是说pull是一个while循环,随时可以跳出,而sax不是,sax是只要解析了,就必须解析完成,在解析过程中在读取到特定tag时调用相应处理事件。这是他们主要的区别。
    而他们的相似性在运行方式上,Pull解析器也提供了类似SAX的事件,开始文档START_DOCUMENT和结束文档END_DOCUMENT,开始元素START_TAG和结束元素END_TAG,遇到元素内容TEXT等,但需要调用next() 方法提取它们(主动提取事件)。



SAX解析的基本用法
* 解析方式:一行一行进行解析,从上到下解析过程中,遇到不同的内容就会执行不同的方法。
* 读到开始标签时执行startElement方法,读到换行,空格或者是标签中的内容时执行characters方法,
* 读到结束标签时执行endElement方法。

PULL解析的方式
try {
//1.创建Pull解析工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//2.创建解析器
XmlPullParser parser = factory.newPullParser();
//3.设置要解析的xml文件
parser.setInput(new FileInputStream("src/books.xml"), "utf-8");
//4.获取事件类型
int type = parser.getEventType();//查看XmlPullParser源码 0:文档的开始 ...
System.out.println("type:"+type);
List<Book> list = new ArrayList<Book>();
Book book = null;
//循环读取数据
while (type != XmlPullParser.END_DOCUMENT) {//循环读取数据直到读到文档结束
switch (type) {
case XmlPullParser.START_TAG://开始标签 2
// System.out.println("开始标签:"+parser.getName());//getName():获取标签名称
if("book".equals(parser.getName())){
book = new Book();
// parser.getAttributeValue(0);//获取属性的值
book.setId(Integer.parseInt(parser.getAttributeValue(null, "id")));
}else if("name".equals(parser.getName())){
book.setName(parser.nextText());//nextText()获取下一个元素的内容(获取当前标签中的内容)
}else if("author".equals(parser.getName())){
book.setAuthor(parser.nextText());
}else if("price".equals(parser.getName())){
book.setPrice(Double.parseDouble(parser.nextText()));
}
break;
case XmlPullParser.END_TAG://结束标签 3
// System.out.println("结束标签:"+parser.getName());
if("book".equals(parser.getName())){
list.add(book);
}
break;
default:
break;
}
type = parser.next();//继续解析下一个元素
}
System.out.println("读取完毕");
for (Book b : list) {
System.out.println(b.getId()+"--"+b.getName()+"--"+b.getAuthor()+"--"+b.getPrice());
}
} catch (Exception e) {
e.printStackTrace();
}

SAX解析books.xml文件,把数据封装成对象保存在集合中List<Object>

class MyContentHandler3 extends DefaultHandler{
List<Book> list = new ArrayList<Book>();
Book book = null;
String tagName = "";//当前读到的标签名称
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
tagName = qName;
if("book".equals(qName)){
book = new Book();
int id = Integer.parseInt(attributes.getValue("id"));//getValue(0):第一个属性 1:第二个属性
book.setId(id);
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
tagName = "";//不设置就会报错,读到换行或空格时也会执行characters方法
if("book".equals(qName)){
list.add(book);
book = null;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if("name".equals(tagName)){
String name = new String(ch,start,length);
book.setName(name);
}else if("author".equals(tagName)){
String author = new String(ch,start,length);
book.setAuthor(author);
}else if("price".equals(tagName)){
String price = new String(ch,start,length);
book.setPrice(Double.parseDouble(price));
}
}
}

try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
MyContentHandler3 mHandler3 = new MyContentHandler3();
reader.setContentHandler(mHandler3);
reader.parse("src/books.xml");
//遍历数据
for (Book book : mHandler3.list) {
System.out.println(book.getId()+"--"+book.getName()+"--"+book.getAuthor()+"--"+book.getPrice());
}
} catch (Exception e) {
e.printStackTrace();
}


0 0
原创粉丝点击