现在的位置: 首页 > 综合 > 正文

Android 创建与解析XML Android 创建与解析XML(一)—— 概述Android 创建与解析XML(二)—— Dom方式Android 创建与解析XML(三)—— Sax方式Android 创建与解析XML(四)—— Pull方式Android 创建与解析XML(五)—— Dom4j方式Android 创建与解析XML(六)—— 比较与使用

2017年12月12日 ⁄ 综合 ⁄ 共 41187字 ⁄ 字号 评论关闭
 

Android 创建与解析XML(一)—— 概述

分类: Android 84016人阅读 评论(0) 收藏 举报

Android 是最常用的智能手机平台,XML 是数据交换的标准媒介,Android 中可以使用标准的XML生成器、解析器、转换器 API,对 XML 进行解析和转换。

XML,相关有DOM、SAX、JDOM、DOM4J、Xerces、JAXP等一堆概念,但是很多人总是会弄混他们之间的关系,这对我们理解XML文件的创建和解析很不利。要挑选一个适合在Android平台上使用的XML解析方案,我们还是得先把这些概念厘清。

XML基本概念

DOM(Document Object Model,文档对象模型)和SAX(Simple API for XML,简单XML应用接口),是JAXP(Java API
for XML Processing,Java XML处理的应用接口)定义的2种不同的对XML文档进行分析、处理的方法。

DOM方法是用标准对象模型表示 XML 文档;SAX方法则使用事件模型来处理程序来处理XML。

JAXP完成了对SAX、DOM的包装,它向应用程序提供针对DOM的DocumentBuilderFactory、 DocumentBuilder;以及针对SAX的SAXParserFactory、SAXParser抽象工厂类。在Jave SE中JAXP对应javax.xml.parsers包,DOM对应org.w3c.dom,SAX对应org.xml.sax。

Xerces首先继承并实现了javax.xml.parser包内的SAXParser、SAXParserFactory、DocumentBuilder、DocumentBuilderFactory等抽象类,并提供了JAXP中所定义的DOM、SAX(以及StAX,后面会介绍)这些XML解析方法的实现和相应的Parser。

JDOMDOM4J,是因为有人觉得W3C的DOM标准API太过难用而着手开发的替代API,它们和JAXP一样都是对DOM、SAX的封装,不过JDOM、DOM4J做了更多的事情,相当于上面提到JAXP接口+Xerces DOM实现部分。JDOM并没有自己开发Parser,所以还是需要利用Xerces的Parser部分,而DOM4J自带一个名为Alfred2的Parser,当然也可以使用Xerces的Parser。看起来JAXP具备更好的可移植性,即我们可以通过修改配置文件切换不同的DOM实现和SAX、DOM
Parser,JDOM、DOM4J虽然也可以切换Parser,但是DOM实现是无法切换的。(参考: Java XML API 漫谈  和  JAXP全面介绍


XML创建与解析

XML创建主要四种方式:Dom、Sax、Pull、Dom4j

XML解析主要四种方式:Dom、Sax、Pull、Dom4j

其中,利用Dom、Sax、Pull、Dom4j创建的标准XML格式文件,可以由任何一种Dom、Sax、Pull、Dom4j解析方式进行解析。

Android中解析XML

DOM解析器,是通过将XML文档解析成树状模型并将其放入内存来完成解析工作的,然后对文档的操作都是在这个树状模型上完成的。这个在内存中的文档树将是文档实际大小的几倍。这样做的好处是结构清晰、操作方便,而带来的麻烦就是极其耗费系统资源。

SAX解析器,正好克服了DOM的缺点,分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档,它可以在某个条件得到满足时停止解析。

DOM与SAX比较

下面的表格列出了SAX和DOM在一些方面的对照:

SAX DOM
顺序读入文档并产生相应事件,可以处理任何大小的XML文档 在内存中创建文档树,不适于处理大型XML文档。
只能对文档按顺序解析一遍,不支持对文档的随意访问。 可以随意访问文档树的任何部分,没有次数限制。
只能读取XML文档内容,而不能修改 可以随意修改文档树,从而修改XML文档。
开发上比较复杂,需要自己来实现事件处理器。 易于理解,易于开发。
对开发人员而言更灵活,可以用SAX创建自己的XML对象模型。 已经在DOM基础之上创建好了文档树。

通过对SAX和DOM的分析,它们各有自己的不同应用领域:

SAX适于处理下面的问题:

  1. 对大型文档进行处理。
  2. 只需要文档的部分内容,或者只需要从文档中得到特定信息。
  3. 想创建自己的对象模型的时候。

DOM适于处理下面的问题:

  1. 需要对文档进行修改
  2. 需要随机对文档进行访问,例如XSLT解析器。

DOM和SAX的应用场景
1、数据修改:如果打算对数据作出更改并将它输出为 XML,那么在大多数情况下,DOM 是适当的选择。并不是说使用 SAX 就不能更改数据,但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。
2、数据容量: 对于大型文件,SAX 是更好的选择。
3、数据使用:如果只有数据中的少量部分会被使用,那么使用 SAX 来将该部分数据提取到应用程序中可能更好。 另一方面,如果您知道自己以后会回头引用已处理过的大量信息,那么 SAX 也许不是恰当的选择。
4、速度要求: SAX 实现通常要比 DOM 实现速度更快
基于上面的分析,在基于Android系统的内存和CPU资源比较有限的手持设备上,只要我们不需要修改XML数据或者随机的访问XML数据,SAX尽管可能需要更多的编码工作,但是为了更小的内存和CPU消耗,还是值得的。

另外,Android SDK中已经包含了JAXP对应的javax.xml.parsers包,SAX对应org.xml.sax,DOM对应的org.w3c.dom包,加上Android还提供了android.sax这样的包来方便SAX Handle的开发,基于JAXP和SAX这样的标准方法来开发不仅复杂度不高,即使出现问题在讨论组中寻求解决方案也是比较容易的。(参考: 使用
SAX 处理 XML 文档
   和   DOM SAX JAXP DOM4J JDOM xerces解析器

Android中解析XML实现

基于上面的分析,采用JAXP+SAX的方案是我比较看好的。我们首先需要又一个SAXParserFactory的实例,然后从工厂中得到一个SAXParser实例,进而获取一个XMLReader;接下来新建一个Handler类继承自SAX Helpler的DefaultHandler,并实现startDocument()、startElement()、endElement()以及endDocument()等方法,并把这个Handler作为XMLReader的Content Handler;最后以带解析的XML文档为参数调用XMLReader的parse方法即可。具体的代码参考:Android
上使用 XML
  和  Android 3.0 平台上创建和解析 XML

1、Android系统中的DOM和SAX实现
Android SDK中包含了JAXP对应javax.xml.parsers包,SAX对应的org.xml.sax,DOM对应的org.w3c.dom包,所以我们就已经有了XML解析所需的JAXP——对SAX和DOM的封装(抽象类)以及SAX和DOM接口类,但是对于JAXP抽象类的实现,以及DOM和SAX接口类的实现在哪里呢?是和Java
SE 5.0一样用了Xerces吗? 不!
通过查看Android 1.5的源代码,我看到这部分的代码来自Apache Harmony这个开源的Java SE实现,位于./dalvik/libcore/xml/src/main/java/org/apache/harmony/xml目录。这里包含有一个完整的DOM实现(dom目录),对于javax.xml.parser下的抽象类的实现(parser目录),以及对于SAX接口类的实现(除此以外还包括对XMLPullParser接口的实现)。

2、XmlPull 和 KXML2
XmlPull解析器,提供了资源有限的环境(如J2ME)应用使用的XML解析API,XPP提供了非常简单的接口——包含一个接口、一个异常、一个建立解析器的factory。它采用了类似JAXP的工厂模式,把接口设计和实现分离,KXML2就是一个为J2ME环境优化的一个实现。在Android SDK中,已经包含了XmlPull(org.xmlpull.v1包)以及它的一个AddOn——SAX2 Driver——它使得我们可以通过SAX2的API来操纵XmlPull
Parser。另外,通过sourcecode,我们可以看到Android SDK中的XmlPull的实现是KXML2,位于./dalvik/libcore/xml/src/main/java/org/kxml2目录。Apache Harmony的目录中同样有一个ExpatPullParser类实现了XMLPullParser接口,但是却没有XmlSerializer接口的实现,所以只能说Android中的Harmony也部分实现了XmlPull API。XmlPull+KXML2是下一步我要实践的方案,到时候还得学习一下如何“公平”的比较两者的性能。

3、StAX

尽管Android中还没有提供相应的支持,但是Streaming API for XML (StAX) 作为用Java语言处理 XML的最新标准,无论从性能还是可用性上都有出色的表现。它不仅提供了一个快捷、易用、占用内存少的 XML 解析器,它还提供了过滤器接口,允许程序员向应用程序业务逻辑隐藏不需要的文档细节。感兴趣的朋友可以看一看下面的文章。

使用 StAX 解析 XML,第 1 部分: Streaming API for XML (StAX) 简介

使用 StAX 解析 XML,第 2 部分: 拉式解析和事件

使用 StAX 解析 XML,第 3 部分: 使用定制事件和编写 XML

参考推荐:

Android中解析XML数据

android解析XML总结(SAX、Pull、Dom三种方式)

Android 解析XML文件的三种方式 DOM,SAX,PULL

android解析xml文件的方式(推荐,共三篇)

 

Android 上使用 XML

Android 上使用 XML 和 JSON

Android 3.0 平台上创建和解析 XML

Android XML解析学习——创建XML(共六篇,推荐

 

Android 创建与解析XML(二)—— Dom方式

分类: Android 3888人阅读 评论(0) 收藏 举报

1. Dom概述

Dom方式创建XML,应用了标准xml构造器 javax.xml.parsers.DocumentBuilder 来创建 XML 文档,需要导入以下内容

javax.xml.parsers

javax.xml.parsers.DocumentBuilder 

javax.xml.parsers.DocumentBuilderFactory 

javax.xml.parsers.ParserConfigurationException;

javax.xml.transform

javax.xml.transform.TransformerFactory 

javax.xml.transform.Transformer 

javax.xml.transform.dom.DOMSource 

javax.xml.transform.stream.StreamResult 

javax.xml.transform.OutputKeys;

javax.xml.transform.TransformerFactoryConfigurationError;

javax.xml.transform.TransformerConfigurationException;

javax.xml.transform.TransformerException;

org.w3c.dom 

org.w3c.dom.Document;

org.w3c.dom.Element;

org.w3c.dom.Node;

org.w3c.dom.DOMException;

org.w3c.dom.NodeList;

org.xml.sax.SAXException;

sdk源码查看路径google code

创建和解析xml的效果图:




2、Dom 创建 XML

Dom,借助 javax.xml.parsers.DocumentBuilder,可以创建 org.w3c.dom.Document 对象。

使用来自 DocumentBuilderFactory 的 DocumentBuilder 对象在 Android 设备上创建与解析 XML 文档。您将使用 XML pull 解析器的扩展来解析 XML 文档。

Code

  1. /** Dom方式,创建 XML  */  
  2. public String domCreateXML() {  
  3.     String xmlWriter = null;  
  4.       
  5.     Person []persons = new Person[3];       // 创建节点Person对象  
  6.     persons[0] = new Person(1"sunboy_2050""http://blog.csdn.net/sunboy_2050");  
  7.     persons[1] = new Person(2"baidu""http://www.baidu.com");  
  8.     persons[2] = new Person(3"google""http://www.google.com");  
  9.       
  10.     try {  
  11.         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
  12.         DocumentBuilder builder = factory.newDocumentBuilder();  
  13.         Document doc = builder.newDocument();  
  14.           
  15.         Element eleRoot = doc.createElement("root");  
  16.         eleRoot.setAttribute("author""homer");  
  17.         eleRoot.setAttribute("date""2012-04-26");  
  18.         doc.appendChild(eleRoot);  
  19.           
  20.         int personsLen = persons.length;  
  21.         for(int i=0; i<personsLen; i++) {  
  22.             Element elePerson = doc.createElement("person");  
  23.             eleRoot.appendChild(elePerson);  
  24.               
  25.             Element eleId = doc.createElement("id");  
  26.             Node nodeId = doc.createTextNode(persons[i].getId() + "");  
  27.             eleId.appendChild(nodeId);  
  28.             elePerson.appendChild(eleId);  
  29.   
  30.             Element eleName = doc.createElement("name");  
  31.             Node nodeName = doc.createTextNode(persons[i].getName());  
  32.             eleName.appendChild(nodeName);  
  33.             elePerson.appendChild(eleName);  
  34.   
  35.             Element eleBlog = doc.createElement("blog");  
  36.             Node nodeBlog = doc.createTextNode(persons[i].getBlog());  
  37.             eleBlog.appendChild(nodeBlog);  
  38.             elePerson.appendChild(eleBlog);  
  39.         }  
  40.           
  41.           
  42.         Properties properties = new Properties();  
  43.         properties.setProperty(OutputKeys.INDENT, "yes");  
  44.         properties.setProperty(OutputKeys.MEDIA_TYPE, "xml");  
  45.         properties.setProperty(OutputKeys.VERSION, "1.0");  
  46.         properties.setProperty(OutputKeys.ENCODING, "utf-8");  
  47.         properties.setProperty(OutputKeys.METHOD, "xml");  
  48.         properties.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");  
  49.           
  50.         TransformerFactory transformerFactory = TransformerFactory.newInstance();  
  51.         Transformer transformer = transformerFactory.newTransformer();  
  52.         transformer.setOutputProperties(properties);  
  53.           
  54.         DOMSource domSource = new DOMSource(doc.getDocumentElement());  
  55.         OutputStream output = new ByteArrayOutputStream();  
  56.         StreamResult result = new StreamResult(output);  
  57.         transformer.transform(domSource, result);  
  58.           
  59.         xmlWriter = output.toString();  
  60.           
  61.     } catch (ParserConfigurationException e) {      // factory.newDocumentBuilder  
  62.         e.printStackTrace();  
  63.     } catch (DOMException e) {                      // doc.createElement  
  64.         e.printStackTrace();  
  65.     } catch (TransformerFactoryConfigurationError e) {      // TransformerFactory.newInstance  
  66.         e.printStackTrace();  
  67.     } catch (TransformerConfigurationException e) {     // transformerFactory.newTransformer  
  68.         e.printStackTrace();  
  69.     } catch (TransformerException e) {              // transformer.transform  
  70.         e.printStackTrace();  
  71.     } catch (Exception e) {  
  72.         e.printStackTrace();  
  73.     }  
  74.       
  75.     savedXML(fileName, xmlWriter.toString());  
  76.       
  77.     return xmlWriter.toString();  
  78. }  

运行结果:


3、Dom 解析 XML

Dom方式,解析XML是创建XML的逆过程,主要用到了builder.parse(is)进行解析,然后通过Tag、NodeList、Element、childNotes等得到Element和Node属性或值。

Code

  1. /** Dom方式,解析 XML  */  
  2. public String domResolveXML() {  
  3.     StringWriter xmlWriter = new StringWriter();  
  4.       
  5.     InputStream is= readXML(fileName);  
  6.     try {  
  7.         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
  8.         DocumentBuilder builder = factory.newDocumentBuilder();  
  9.         Document doc = builder.parse(is);  
  10.   
  11.         doc.getDocumentElement().normalize();  
  12.         NodeList nlRoot = doc.getElementsByTagName("root");  
  13.         Element eleRoot = (Element)nlRoot.item(0);  
  14.         String attrAuthor = eleRoot.getAttribute("author");  
  15.         String attrDate = eleRoot.getAttribute("date");  
  16.         xmlWriter.append("root").append("\t\t");  
  17.         xmlWriter.append(attrAuthor).append("\t");  
  18.         xmlWriter.append(attrDate).append("\n");  
  19.           
  20.         NodeList nlPerson = eleRoot.getElementsByTagName("person");  
  21.         int personsLen = nlPerson.getLength();  
  22.         Person []persons = new Person[personsLen];  
  23.         for(int i=0; i<personsLen; i++) {  
  24.             Element elePerson = (Element) nlPerson.item(i);     // person节点  
  25.             Person person = new Person();                       // 创建Person对象  
  26.               
  27.             NodeList nlId = elePerson.getElementsByTagName("id");  
  28.             Element eleId = (Element)nlId.item(0);  
  29.             String id = eleId.getChildNodes().item(0).getNodeValue();  
  30.             person.setId(Integer.parseInt(id));  
  31.               
  32.             NodeList nlName = elePerson.getElementsByTagName("name");  
  33.             Element eleName = (Element)nlName.item(0);  
  34.             String name = eleName.getChildNodes().item(0).getNodeValue();  
  35.             person.setName(name);  
  36.               
  37.             NodeList nlBlog = elePerson.getElementsByTagName("blog");  
  38.             Element eleBlog = (Element)nlBlog.item(0);  
  39.             String blog = eleBlog.getChildNodes().item(0).getNodeValue();  
  40.             person.setBlog(blog);  
  41.               
  42.             xmlWriter.append(person.toString()).append("\n");  
  43.             persons[i] = person;  
  44.         }  
  45.           
  46.     } catch (ParserConfigurationException e) {      // factory.newDocumentBuilder  
  47.         e.printStackTrace();  
  48.     } catch (SAXException e) {      // builder.parse  
  49.         e.printStackTrace();  
  50.     } catch (IOException e) {       // builder.parse  
  51.         e.printStackTrace();  
  52.     } catch (Exception e) {  
  53.         e.printStackTrace();  
  54.     }  
  55.       
  56.     return xmlWriter.toString();  
  57. }  

运行结果:

4、Person类

Person类,是创建xml的单位实例,基于Java面向对象定义的一个类

  1. public class Person {  
  2.     private int id;  
  3.     private String name;  
  4.     private String blog;  
  5.       
  6.     public Person() {  
  7.         this.id = -1;  
  8.         this.name = "";  
  9.         this.blog = "";  
  10.     }  
  11.   
  12.     public Person(int id, String name, String blog) {  
  13.         this.id = id;  
  14.         this.name = name;  
  15.         this.blog = blog;  
  16.     }  
  17.       
  18.     public Person(Person person) {  
  19.         this.id = person.id;  
  20.         this.name = person.name;  
  21.         this.blog = person.blog;  
  22.     }  
  23.   
  24.     public Person getPerson(){  
  25.         return this;  
  26.     }  
  27.       
  28.     public void setId(int id) {  
  29.         this.id = id;  
  30.     }  
  31.       
  32.     public int getId(){  
  33.         return this.id;  
  34.     }  
  35.       
  36.     public void setName(String name) {  
  37.         this.name = name;  
  38.     }  
  39.   
  40.     public String getName() {  
  41.         return this.name;  
  42.     }  
  43.   
  44.     public void setBlog(String blog) {  
  45.         this.blog = blog;  
  46.     }  
  47.   
  48.     public String getBlog() {  
  49.         return this.blog;  
  50.     }  
  51.   
  52.     public String toString() {  
  53.         return "Person \nid = " + id + "\nname = " + name + "\nblog = " + blog + "\n";  
  54.     }  
  55. }  

代码下载

参考推荐:

org.w3c.dom

javax.xml.parsers

javax.xml.transform

dom创建xml

java dom创建xml

 

Android 创建与解析XML(三)—— Sax方式

分类: Android 3160人阅读 评论(0) 收藏 举报

1. Sax概述

SAX是一种占用内存少且解析速度快的解析器,它采用的是事件启动,不需要解析完整个文档,而是按照内容顺序看文档某个部分是否符合xml语法,如果符合就触发相应的事件,所谓的事件就是些回调方法(callback),这些方法 定义在ContentHandler中,下面是其主要方法:
startDocument():当遇到文档的时候就触发这个事件 调用这个方法 可以在其中做些预处理工作,如:申请对象资源
endDocument():当结束文档的时候就触发这个事件 调用这个方法 可以在其中做些善后工作,如:释放申请的对象资源
startElement(String namespaceURI, String localName, String qName, Attributes atts):当遇开始标签的时候就会触发这个方法。
endElement(String uri, String localName, String name):当遇到结束标签时触发这个事件,调用此法可以做些善后工作。
charachers(char [] ch, int start, int length):当遇到xml内容时触发这个方法,用new String(ch,start,length)可以接受内容。 
Sax方式创建XML,应用了标准xml构造器 javax.xml.transform.sax.TransformerHandler 事件来创建 XML 文档,需要导入以下内容

javax.xml.transform

javax.xml.transform.sax.SAXTransformerFactory;
javax.xml.transform.sax.TransformerHandler;
javax.xml.transform.Transformer;
javax.xml.transform.TransformerConfigurationException;
javax.xml.transform.TransformerFactoryConfigurationError;
javax.xml.transform.OutputKeys;
javax.xml.transform.stream.StreamResult;
javax.xml.transform.sax.SAXTransformerFactory;

javax.xml.parsers

javax.xml.parsers.SAXParser;

javax.xml.parsers.SAXParserFactory;

javax.xml.parsers.FactoryConfigurationError;

javax.xml.parsers.ParserConfigurationException;

org.xml.sax

org.xml.sax.Attributes;
org.xml.sax.SAXException;
org.xml.sax.helpers.AttributesImpl;
org.xml.sax.helpers.DefaultHandler;

sdk源码查看路径google code

Sax 创建和解析 XML 的效果图:

2、Sax 创建 XML

首先,SAXTransformerFactory.newInstance() 创建一个工厂实例 factory

接着,factory.newTransformerHandler() 获取 TransformerHandler 的 handler 对象

然后,通过 handler 事件创建handler.getTransformer()、 handler.setResult(result),以及 startDocument()、startElement、characters、endElement、endDocument()等

Code

  1. /** Sax方式,创建 XML  */  
  2. public String saxCreateXML(){  
  3.     StringWriter xmlWriter = new StringWriter();  
  4.   
  5.     Person []persons = new Person[3];       // 创建节点Person对象  
  6.     persons[0] = new Person(1"sunboy_2050""http://blog.csdn.net/sunboy_2050");  
  7.     persons[1] = new Person(2"baidu""http://www.baidu.com");  
  8.     persons[2] = new Person(3"google""http://www.google.com");  
  9.       
  10.     try {  
  11.         SAXTransformerFactory factory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();  
  12.         TransformerHandler handler = factory.newTransformerHandler();  
  13.           
  14.         Transformer transformer = handler.getTransformer();     // 设置xml属性  
  15.         transformer.setOutputProperty(OutputKeys.INDENT, "yes");  
  16.         transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");  
  17.         transformer.setOutputProperty(OutputKeys.VERSION, "1.0");  
  18.           
  19.         StreamResult result = new StreamResult(xmlWriter);      // 保存创建的xml  
  20.         handler.setResult(result);  
  21.           
  22.         handler.startDocument();  
  23.         AttributesImpl attr = new AttributesImpl();  
  24.           
  25.         attr.clear();  
  26.         attr.addAttribute("""""author""""homer");  
  27.         attr.addAttribute("""""date""""2012-04-27");  
  28.         handler.startElement("""""root", attr);  
  29.           
  30.         int personsLen = persons.length;  
  31.         for(int i=0; i<personsLen; i++){  
  32.             attr.clear();  
  33.             handler.startElement("""""person", attr);  
  34.               
  35.             attr.clear();  
  36.             handler.startElement("""""id", attr);  
  37.             String id = persons[i].getId() + "";  
  38.             handler.characters(id.toCharArray(), 0, id.length());  
  39.             handler.endElement("""""id");  
  40.   
  41.             attr.clear();  
  42.             handler.startElement("""""name", attr);  
  43.             String name = persons[i].getName();  
  44.             handler.characters(name.toCharArray(), 0, name.length());  
  45.             handler.endElement("""""name");  
  46.   
  47.             attr.clear();  
  48.             handler.startElement("""""blog", attr);  
  49.             String blog = persons[i].getBlog();  
  50.             handler.characters(blog.toCharArray(), 0, blog.length());  
  51.             handler.endElement("""""blog");  
  52.               
  53.             handler.endElement("""""person");  
  54.         }  
  55.           
  56.         handler.endElement("""""root");  
  57.         handler.endDocument();  
  58.           
  59.     } catch (TransformerFactoryConfigurationError e) {      // SAXTransformerFactory.newInstance  
  60.         e.printStackTrace();  
  61.     } catch (TransformerConfigurationException e) {         // factory.newTransformerHandler  
  62.         e.printStackTrace();  
  63.     } catch (IllegalArgumentException e) {      // transformer.setOutputProperty  
  64.         e.printStackTrace();  
  65.     } catch (SAXException e) {      // handler.startDocument  
  66.         e.printStackTrace();  
  67.     } catch (Exception e) {  
  68.         e.printStackTrace();  
  69.     }  
  70.       
  71.     savedXML(fileName, xmlWriter.toString());  
  72.     return xmlWriter.toString();  
  73. }  

运行结果:

3、Sax解析XML

Code

  1.     /** Sax方式,解析 XML  */  
  2.     public String saxResolveXML(){  
  3.         StringWriter xmlWriter = new StringWriter();  
  4.   
  5.         InputStream is = readXML(fileName);  
  6.         try {  
  7.             SAXParserFactory factory = SAXParserFactory.newInstance();  
  8.             SAXParser saxParser = factory.newSAXParser();  
  9.               
  10.             PersonHandler handler = new PersonHandler();    // person处理Handler  
  11.             saxParser.parse(is, handler);                   // handler解析xml  
  12.               
  13.             // 获取解析的xml  
  14.             String xmlHeader = handler.getXMLHeader();  
  15.             xmlWriter.append(xmlHeader);  
  16.               
  17.             List<Person> personsList = handler.getPersons();  
  18.             int personsLen = personsList.size();  
  19.             for(int i=0; i<personsLen; i++){  
  20.                 xmlWriter.append(personsList.get(i).toString()).append("\n");  
  21.             }  
  22.               
  23.         } catch (FactoryConfigurationError e) {         // SAXParserFactory.newInstance  
  24.             e.printStackTrace();  
  25.         } catch (ParserConfigurationException e) {      // factory.newSAXParser  
  26.             e.printStackTrace();  
  27.         } catch (SAXException e) {          // factory.newSAXParser  
  28.             e.printStackTrace();  
  29.         } catch (IllegalArgumentException e) {      // saxParser.parse  
  30.             e.printStackTrace();  
  31.         } catch (IOException e) {           // saxParser.parse  
  32.             e.printStackTrace();  
  33.         } catch (Exception e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.           
  37.         return xmlWriter.toString();  
  38.     }  
  39.       
  40.     /** Handler处理类 */  
  41.     private final class PersonHandler extends DefaultHandler{  
  42.         private List<Person> personsList = null;  // 保存person  
  43.         private Person person = null;  
  44.         private StringBuffer xmlHeader;             // 保存xml头部信息  
  45.         private String tag = null;          // xml Element  
  46.           
  47.         /** 返回解析的xml头部信息 */  
  48.         public String getXMLHeader(){  
  49.             return xmlHeader.toString();  
  50.         }  
  51.           
  52.         /** 返回解析的Person实例数组 */  
  53.         public List<Person> getPersons(){  
  54.             return personsList;  
  55.         }  
  56.           
  57.         @Override  
  58.         public void startDocument() throws SAXException{  
  59.             super.startDocument();  
  60.             personsList = new ArrayList<Person>();  
  61.             xmlHeader = new StringBuffer();  
  62.         }  
  63.           
  64.         @Override  
  65.         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{  
  66.             super.startElement(uri, localName, qName, attributes);  
  67.             if("root".equals(localName)) {  
  68.                 String attrAuthor = attributes.getValue(0);  
  69.                 String attrDate = attributes.getValue(1);  
  70.                 xmlHeader.append("root").append("\t\t");  
  71.                 xmlHeader.append(attrAuthor).append("\t");  
  72.                 xmlHeader.append(attrDate).append("\n");  
  73.             } else if("person".equals(localName)) {  
  74.                 person = new Person();  
  75.             }   
  76.             tag = localName;  
  77.         }  
  78.           
  79.         @Override  
  80.         public void characters(char[] ch, int start, int length) throws SAXException {  
  81.             super.characters(ch, start, length);  
  82.             if (null != tag) {  
  83.                 String value = new String(ch, start, length);  
  84.                 System.out.println("value = " + value);  
  85.                 if ("id".equals(tag)) {  
  86.                     person.setId(new Integer(value));  
  87.                 } else if ("name".equals(tag)) {  
  88.                     person.setName(value);  
  89.                 } else if ("blog".equals(tag)) {  
  90.                     person.setBlog(value);  
  91.                 }  
  92.             }  
  93.         }  
  94.           
  95.         @Override  
  96.         public void endElement(String uri, String localName, String qName) throws SAXException {  
  97.             if("person".equals(qName)) {  
  98.                 personsList.add(person);  
  99.                 person = null;  
  100.             }  
  101.             tag = null;  
  102.             super.endElement(uri, localName, qName);  
  103.         }  
  104.           
  105.         @Override  
  106.         public void endDocument() throws SAXException{  
  107. //          personsList = null;  
  108.             super.endDocument();  
  109.         }  
  110.     }  

运行结果:

4、Person类

请参见前面博客 Android 创建与解析XML(二)—— Dom方式 【4、Person类】

 

Android 创建与解析XML(四)—— Pull方式

分类: Android 3906人阅读 评论(1) 收藏 举报

1、Pull概述

Android系统中和创建XML相关的包为org.xmlpull.v1,在这个包中不仅提供了用于创建XML的 XmlSerializer,还提供了用来解析XML的Pull方式解析器 XmlPullParser

XmlSerializer没有像XmlPullParser那样提取XML事件,而是把它们推出到数据流OutputStream或Writer中。

XmlSerializer提供了很直观的API,即使用startDocument开始文档,endDocument结束文档,startTag开始元素,endTag结束元素,text添加文本等。

Pull方式创建XML,应用了标准xml构造器 org.xmlpull.v1.XmlSerializer来创建 XML ,org.xmlpull.v1.XmlPullParser来解析XML,需要导入以下内容

org.xmlpull.v1

org.xmlpull.v1.XmlPullParser;

org.xmlpull.v1.XmlPullParserException;

org.xmlpull.v1.XmlPullParserFactory;

org.xmlpull.v1.XmlSerializer;

sdk源码查看路径google code

Pull 创建和解析 XML 的效果图:

2、Pull 创建 XML

pull方式,创建xml是通过 XmlSerializer 类实现

首先,通过XmlSerializer得到创建xml的实例 xmlSerializer

接着,通过 xmlSerializer 设置输出 xmlSerializer.setOutput,xmlSerializer.startDocument("utf-8", null)设置xml属性等

然后,通过 xmlSerializer 创建 startDocument、startTag、text、endTag、endDocument等

Code

  1.     /** Pull方式,创建 XML  */  
  2.     public String pullXMLCreate(){  
  3.         StringWriter xmlWriter = new StringWriter();  
  4.   
  5.         Person []persons = new Person[3];       // 创建节点Person对象  
  6.         persons[0] = new Person(1"sunboy_2050""http://blog.csdn.net/sunboy_2050");  
  7.         persons[1] = new Person(2"baidu""http://www.baidu.com");  
  8.         persons[2] = new Person(3"google""http://www.google.com");  
  9.           
  10.         try {  
  11. //          // 方式一:使用Android提供的实用工具类android.util.Xml  
  12. //          XmlSerializer xmlSerializer = Xml.newSerializer();        
  13.               
  14.             // 方式二:使用工厂类XmlPullParserFactory的方式  
  15.             XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  
  16.             XmlSerializer xmlSerializer = factory.newSerializer();  
  17.               
  18.             xmlSerializer.setOutput(xmlWriter);             // 保存创建的xml  
  19.               
  20.             xmlSerializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output"true);  
  21. //          xmlSerializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation", " ");         // 设置属性  
  22. //          xmlSerializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-line-separator", "\n");  
  23.             xmlSerializer.startDocument("utf-8"null);     // <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>   
  24.               
  25.             xmlSerializer.startTag("""root");  
  26.             xmlSerializer.attribute("""author""homer");  
  27.             xmlSerializer.attribute("""date""2012-04-28");  
  28.               
  29.             int personsLen = persons.length;  
  30.             for(int i=0; i<personsLen; i++) {  
  31.                 xmlSerializer.startTag("""person");       // 创建person节点  
  32.                   
  33.                 xmlSerializer.startTag("""id");  
  34.                 xmlSerializer.text(persons[i].getId()+"");  
  35.                 xmlSerializer.endTag("""id");  
  36.   
  37.                 xmlSerializer.startTag("""name");  
  38.                 xmlSerializer.text(persons[i].getName());  
  39.                 xmlSerializer.endTag("""name");  
  40.   
  41.                 xmlSerializer.startTag("""blog");  
  42.                 xmlSerializer.text(persons[i].getBlog());  
  43.                 xmlSerializer.endTag("""blog");  
  44.                   
  45.                 xmlSerializer.endTag("""person");  
  46.             }  
  47.               
  48.             xmlSerializer.endTag("""root");  
  49.             xmlSerializer.endDocument();  
  50.               
  51.         } catch (XmlPullParserException e) {        // XmlPullParserFactory.newInstance  
  52.             e.printStackTrace();  
  53.         } catch (IllegalArgumentException e) {      // xmlSerializer.setOutput  
  54.             e.printStackTrace();  
  55.         } catch (IllegalStateException e) {         // xmlSerializer.setOutput  
  56.             e.printStackTrace();  
  57.         } catch (IOException e) {       // xmlSerializer.setOutput  
  58.             e.printStackTrace();  
  59.         } catch (Exception e) {  
  60.             e.printStackTrace();  
  61.         }  
  62.           
  63.         savedXML(fileName, xmlWriter.toString());  
  64.         return xmlWriter.toString();  
  65.     }  


运行结果:


3、Pull 解析 XML

pull方式,解析xml是通过 XmlPullParser 类实现

首先,通过XmlPullParser得到解析xml的实例 xpp

接着,通过 xpp设置输入 xpp.setInput(is, "utf-8"),声明定义保存xml信息的数据结构(如:Person数组)

然后,通过 xpp 解析 START_DOCUMENT、START_TAG、TEXT、END_TAG、END_DOCUMENT等

Code

  1.     /** Pull方式,解析 XML  */  
  2.     public String pullXMLResolve(){  
  3.         StringWriter xmlWriter = new StringWriter();  
  4.           
  5.         InputStream is = readXML(fileName);  
  6.         try {  
  7. //          // 方式一:使用Android提供的实用工具类android.util.Xml  
  8. //          XmlPullParser xpp = Xml.newPullParser();  
  9.               
  10.             // 方式二:使用工厂类XmlPullParserFactory的方式  
  11.             XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  
  12.             XmlPullParser xpp = factory.newPullParser();  
  13.               
  14.             xpp.setInput(is, "utf-8");  
  15.               
  16.             List<Person> personsList = null;      // 保存xml的person节点  
  17.             Person person = null;  
  18.             StringBuffer xmlHeader = null;          // 保存xml头部  
  19.             String ele = null;      // Element flag  
  20.               
  21.             int eventType = xpp.getEventType();  
  22.             while(XmlPullParser.END_DOCUMENT != eventType) {  
  23.                 switch (eventType) {  
  24.                 case XmlPullParser.START_DOCUMENT:  
  25.                     personsList = new ArrayList<Person>();        // 初始化persons  
  26.                     xmlHeader = new StringBuffer();             // 初始化xmlHeader  
  27.                     break;  
  28.                       
  29.                 case XmlPullParser.START_TAG:  
  30.                     if("root".equals(xpp.getName())) {  
  31.                         String attrAuthor = xpp.getAttributeValue(0);  
  32.                         String attrDate = xpp.getAttributeValue(1);  
  33.                         xmlHeader.append("root").append("\t\t");  
  34.                         xmlHeader.append(attrAuthor).append("\t");  
  35.                         xmlHeader.append(attrDate).append("\n");  
  36.                     } else if("person".equals(xpp.getName())) {  
  37.                         person = new Person();          // 创建person实例  
  38.                     } else if("id".equals(xpp.getName())) {  
  39.                         ele = "id";  
  40.                     } else if("name".equals(xpp.getName())) {  
  41.                         ele = "name";  
  42.                     } else if("blog".equals(xpp.getName())) {  
  43.                         ele = "blog";  
  44.                     } else {  
  45.                         ele = null;  
  46.                     }  
  47.                     break;  
  48.                       
  49.                 case XmlPullParser.TEXT:  
  50.                     if(null != ele) {  
  51.                         if("id".equals(ele)) {  
  52.                             person.setId(Integer.parseInt(xpp.getText()));  
  53.                         } else if("name".equals(ele)) {  
  54.                             person.setName(xpp.getText());  
  55.                         } else if("blog".equals(ele)) {  
  56.                             person.setBlog(xpp.getText());  
  57.                         }  
  58.                     }  
  59.                     break;  
  60.                       
  61.                 case XmlPullParser.END_TAG:  
  62.                     if("person".equals(xpp.getName())){  
  63.                         personsList.add(person);  
  64.                         person = null;  
  65.                     }  
  66.                     ele = null;  
  67.                     break;  
  68.                 }  
  69.                   
  70.                 eventType = xpp.next();     // 下一个事件类型  
  71.             }  
  72.               
  73.             xmlWriter.append(xmlHeader);  
  74.             int personsLen = personsList.size();  
  75.             for(int i=0; i<personsLen; i++) {  
  76.                 xmlWriter.append(personsList.get(i).toString());  
  77.             }  
  78.               
  79.         } catch (XmlPullParserException e) {        // XmlPullParserFactory.newInstance  
  80.             e.printStackTrace();  
  81.         } catch (Exception e) {  
  82.             e.printStackTrace();  
  83.         }  
  84.           
  85.         return xmlWriter.toString();          
  86.     }  

运行结果:

4、Person类

请参见前面博客 Android 创建与解析XML(二)—— Dom方式 【4、Person类】

代码下载

参考推荐:

org.xmlpull.v1

pull创建xml

 

Android 创建与解析XML(五)—— Dom4j方式

分类: Android 4413人阅读 评论(0) 收藏 举报

1、Dom4j概述

dom4j is an easy to use, open source library for working with XML, XPath and XSLT on the Java platform using the Java Collections Framework and with full support for DOM, SAX and JAXP. 

dom4j官方网址:dom4j

dom4j源码下载:dom4j download

本示例中,需要导入dom4j.jar包,才能引用dom4j相关类,dom4j源码和jar包,请见本示例【源码下载】或访问 dom4j

org.dom4j包,不仅包含创建xml的构建器类DocumentHelper、Element,而且还包含解析xml的解析器SAXReader、Element,包含类如下:

org.dom4j

org.dom4j.DocumentHelper;

org.dom4j.Element;

org.dom4j.io.SAXReader;

org.dom4j.io.XMLWriter;

org.dom4j.DocumentException;

sdk源码查看路径google code

创建和解析xml的效果图:

2、Dom4j 创建 XML

Dom4j,创建xml主要用到了org.dom4j.DocumentHelper、org.dom4j.Document、org.dom4j.io.OutputFormat、org.dom4j.io.XMLWriter

首先,DocumentHelper.createDocument(),创建 org.dom4j.Document 的实例 doc

接着,通过doc,设置xml属性doc.setXMLEncoding("utf-8")、doc.addElement("root")根节点,以及子节点等

然后,定义xml格式并输出,new XMLWriter(xmlWriter, outputFormat)

Code

  1. /** Dom4j方式,创建 XML  */  
  2. public String dom4jXMLCreate(){  
  3.     StringWriter xmlWriter = new StringWriter();  
  4.   
  5.     Person []persons = new Person[3];       // 创建节点Person对象  
  6.     persons[0] = new Person(1"sunboy_2050""http://blog.csdn.net/sunboy_2050");  
  7.     persons[1] = new Person(2"baidu""http://www.baidu.com");  
  8.     persons[2] = new Person(3"google""http://www.google.com");  
  9.       
  10.     try {  
  11.         org.dom4j.Document doc = DocumentHelper.createDocument();  
  12.           
  13.         doc.setXMLEncoding("utf-8");  
  14.           
  15.         org.dom4j.Element eleRoot = doc.addElement("root");  
  16.         eleRoot.addAttribute("author""homer");  
  17.         eleRoot.addAttribute("date""2012-04-25");  
  18.         eleRoot.addComment("dom4j test");  
  19.           
  20.         int personsLen = persons.length;  
  21.         for(int i=0; i<personsLen; i++){  
  22.               
  23.             Element elePerson = eleRoot.addElement("person");   // 创建person节点,引用类为 org.dom4j.Element  
  24.               
  25.             Element eleId = elePerson.addElement("id");  
  26.             eleId.addText(persons[i].getId()+"");  
  27.               
  28.             Element eleName = elePerson.addElement("name");  
  29.             eleName.addText(persons[i].getName());  
  30.               
  31.             Element eleBlog = elePerson.addElement("blog");  
  32.             eleBlog.addText(persons[i].getBlog());  
  33.         }  
  34.   
  35.         org.dom4j.io.OutputFormat outputFormat = new org.dom4j.io.OutputFormat();   // 设置xml输出格式  
  36.         outputFormat.setEncoding("utf-8");  
  37.         outputFormat.setIndent(false);  
  38.         outputFormat.setNewlines(true);  
  39.         outputFormat.setTrimText(true);  
  40.           
  41.         org.dom4j.io.XMLWriter output = new XMLWriter(xmlWriter, outputFormat);     // 保存xml  
  42.         output.write(doc);  
  43.         output.close();  
  44.     } catch (Exception e) {  
  45.         e.printStackTrace();  
  46.     }  
  47.       
  48.     savedXML(fileName, xmlWriter.toString());  
  49.     return xmlWriter.toString();  
  50. }  

运行结果:

3、Dom4j 解析 XML

Dom4j,解析xml主要用到了org.dom4j.io.SAXReader、org.dom4j.Document、doc.getRootElement(),以及ele.getName()、ele.getText()等

首先,创建SAXReader的实例reader,读入xml字节流 reader.read(is)

接着,通过doc.getRootElement()得到root根节点,利用迭代器取得root下一级的子节点eleRoot.elementIterator()等

然后,得到解析的xml内容xmlWriter.append(xmlHeader)、xmlWriter.append(personsList.get(i).toString())


解析一:标准解析(Iterator 迭代)

Code

  1. /** Dom4j方式,解析 XML  */  
  2. public String dom4jXMLResolve(){  
  3.     StringWriter xmlWriter = new StringWriter();  
  4.       
  5.     InputStream is = readXML(fileName);  
  6.     try {  
  7.         SAXReader reader = new SAXReader();  
  8.         org.dom4j.Document doc = reader.read(is);  
  9.   
  10.         List<Person> personsList = null;  
  11.         Person person = null;  
  12.         StringBuffer xmlHeader = new StringBuffer();  
  13.           
  14.           
  15.         Element eleRoot = doc.getRootElement();     // 获得root根节点,引用类为 org.dom4j.Element  
  16.         String attrAuthor = eleRoot.attributeValue("author");  
  17.         String attrDate = eleRoot.attributeValue("date");  
  18.         xmlHeader.append("root").append("\t\t");  
  19.         xmlHeader.append(attrAuthor).append("\t");  
  20.         xmlHeader.append(attrDate).append("\n");  
  21.         personsList = new ArrayList<Person>();  
  22.           
  23.         // 获取root子节点,即person  
  24.         Iterator<Element> iter = eleRoot.elementIterator();  
  25.         for(; iter.hasNext(); ) {  
  26.             Element elePerson = (Element)iter.next();  
  27.               
  28.             if("person".equals(elePerson.getName())){  
  29.                 person = new Person();  
  30.                   
  31.                 // 获取person子节点,即id、name、blog  
  32.                 Iterator<Element> innerIter = elePerson.elementIterator();  
  33.                 for(; innerIter.hasNext();) {  
  34.                     Element ele = (Element)innerIter.next();  
  35.                       
  36.                     if("id".equals(ele.getName())) {  
  37.                         String id = ele.getText();  
  38.                         person.setId(Integer.parseInt(id));  
  39.                     } else if("name".equals(ele.getName())) {  
  40.                         String name = ele.getText();  
  41.                         person.setName(name);  
  42.                     } else if("blog".equals(ele.getName())) {  
  43.                         String blog = ele.getText();  
  44.                         person.setBlog(blog);  
  45.                     }  
  46.                 }  
  47.                   
  48.                 personsList.add(person);  
  49.                 person = null;  
  50.             }  
  51.         }  
  52.           
  53.         xmlWriter.append(xmlHeader);  
  54.         int personsLen = personsList.size();  
  55.         for(int i=0; i<personsLen; i++) {  
  56.             xmlWriter.append(personsList.get(i).toString());  
  57.         }  
  58.           
  59.     } catch (DocumentException e) {  
  60.         e.printStackTrace();  
  61.     } catch (Exception e) {  
  62.         e.printStackTrace();  
  63.     }  
  64.       
  65.     return xmlWriter.toString();  
  66. }  

运行结果:

解析二:选择性解析(XPath路径

Dom4j+XPath,选择性只解析id,doc.selectNodes("//root//person//id")

Code

  1. /** Dom4j方式,解析 XML(方式二)  */  
  2. public String dom4jXMLResolve2(){  
  3.     StringWriter xmlWriter = new StringWriter();  
  4.       
  5.     InputStream is = readXML(fileName);  
  6.     try {  
  7.         org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader();  
  8.         org.dom4j.Document doc = reader.read(is);  
  9.   
  10.         List<Person> personsList = null;  
  11.         Person person = null;  
  12.         StringBuffer xmlHeader = new StringBuffer();  
  13.           
  14.           
  15.         Element eleRoot = doc.getRootElement();     // 获得root根节点,引用类为 org.dom4j.Element  
  16.         String attrAuthor = eleRoot.attributeValue("author");  
  17.         String attrDate = eleRoot.attributeValue("date");  
  18.         xmlHeader.append("root").append("\t\t");  
  19.         xmlHeader.append(attrAuthor).append("\t");  
  20.         xmlHeader.append(attrDate).append("\n");  
  21.         personsList = new ArrayList<Person>();  
  22.           
  23.         @SuppressWarnings("unchecked")  
  24.         List<Element> idList = (List<Element>) doc.selectNodes("//root//person//id");   // 选择性获取全部id  
  25.         Iterator<Element> idIter = idList.iterator();  
  26.         while(idIter.hasNext()){  
  27.             person = new Person();  
  28.               
  29.             Element idEle = (Element)idIter.next();  
  30.             String id = idEle.getText();  
  31.             person.setId(Integer.parseInt(id));  
  32.               
  33.             personsList.add(person);  
  34.         }  
  35.   
  36.         xmlWriter.append(xmlHeader);  
  37.         int personsLen = personsList.size();  
  38.         for(int i=0; i<personsLen; i++) {  
  39.             xmlWriter.append("id = ").append(personsList.get(i).getId()+"").append("\n");  
  40.         }  
  41.           
  42.     } catch (DocumentException e) {  
  43.         e.printStackTrace();  
  44.     } catch (Exception e) {  
  45.         e.printStackTrace();  
  46.     }  
  47.       
  48.     return xmlWriter.toString();  
  49. }  

注:借助 XPath 解析 XML 时,需要导入 jaxen;本示例需要导入的是最新的jaxen包jaxen-1.1.3.jar,可以下载本示例下面【源码下载】或 访问 jaxen
jar

Jaxen is an open source XPath library written in Java. It is adaptable to many different object models, including DOM, XOM, dom4j, and JDOM. Is it also possible to write adapters that treat non-XML trees
such as compiled Java byte code or Java beans as XML, thus enabling you to query these trees with XPath too.

jaxen 官方网址:jaxen

jaxen下载jar包:jaxen jar 或 jaxen
jar

jaxen源码查看:jaxen src 或 jaxen
trunk

运行结果:

4、Person类

请参见前面博客 Android 创建与解析XML(二)—— Dom方式 【4、Person类】

 

Android 创建与解析XML(六)—— 比较与使用

分类: Android 3135人阅读 评论(5) 收藏 举报

目录(?)[+]

前面介绍了四种创建、解析XML的方式:

0、 Android 创建与解析XML(一)——  概述

1、 Android 创建与解析XML(二)—— Dom方式

2、 Android 创建与解析XML(三)—— Sax方式

3、 Android 创建与解析XML(四)—— Pull方式

4、 Android 创建与解析XML(五)—— Dom4j方式

其中,从处理方式看,有的采用了Java处理XML的标准方式,有的是经过第三方改进后的XML处理方式;从事件角度看,有的是基于Dom树节点,有的基于事件处理

为什么创建、解析XML会产生这么多方法呢?四种处理方式的特点各是什么?它们分别更适合什么样的使用场景呢?

一、 XML 通用标准

XML 世界非常庞大,而且还在不断成长,存在大量不同的标准和技术,它们以复杂的方式互相影响。

XML 正在变得越来越强大,并且得到了迅速的发展,它已经证明自己是一种非常有价值的技术,但可能也是一种令人害怕的技术,如果考虑到挂在“XML”一词下面不断变化的各个部分,新手很难确定哪些是 XML 最重要的方面,用户也难以跟踪这个领域出现的新生事物和变化。

标准,有各种各样的形式,而且在同一个领域中常常有多种标准互相竞争,此处把标准定义为:被不同的供应商大量采用的或者有影响的、独立于供应商的组织推荐的规范。

1) XML 1.0 W3C 推荐的标准,衍生出 XML 技术大树的主干。它在 Unicode [Unicode Consortium 技术报告和 ISO 标准]的基础上定义了文本格式的严格规则,以及 DTD  (文档类型定义,Document
Type Definition)验证语言。该规范的当前版本(第 2 版)包含了规范的历次修订。它被 翻译成多种语言,尽管英语版本是唯一的规范版本,就是说只有这个版本被认为具有标准的效力。


2) XML 1.1 ,正在开发中,是改变了结构良好的 XML 文档的定义的第一个修订版。主要的变化是修订了 XML 规范中对字符的处理,使其更自然地适应 Unicode 规范的变化,并通过引用 万维网字符模型(Character Model for the
World Wide Web 1.0
)[开发中],提供了不同 Unicode 版本字符的规范化。XML 1.1 还增加了行结束字符列表,新增加的 NEL 用于在 IBM 大型机系统中表示行结束(EOL)。这种变化存在争议,有人认为对大型机用户带来的有限好处不值得做这种基础性的改变。还有一些其他的争论,因为一些评论者发现所有的修改都太稳妥了,在 XML 版本变换中不会造成各种可能的互操作性问题。

XML 是基于 Standard Generalized Markup Language(标准通用标记语言,SGML)的,后者由 ISO 8879:1986 [ISO 标准]定义。它在很大程度上简化了 SGML,包括一些调整使其更适合于 Web 环境。

二、 XML处理方式

大多数与XML 相关的Java API 在Android 上得到了完全支持,在Android 上可以创建功能强大的移动应用程序,而在Android 上解析XML的技术有三种DOM、SAX、PULL。


1)  DOM 解析技术

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

使用DOM 对XML 文件进行操作时,首先要解析文件,将文件分为独立的元素、属性和注释等,然后以节点树的形式在内存中对XML 文件进行表示,就可以通过节点树访问文档的内容,并根据需要修改文档——这就是DOM的工作原理。DOM 实现时首先为XML 文档的解析定义一组接口,解析器读入整个文档,然后构造一个驻留内存的树结构,这样代码就可以使用DOM接口来操作整个树结构。

DOM 解析流程:

2)  SAX 解析技术

SAX(Simple API for XML,XML 简单应用程序接口),是一个公共的基于事件的XML 文档解析标准。它以事件作为解析XML 文件的模式,它将XML 文件转化成一系列的事件,由不同的事件处理器来决定如何处理。SAX是一个解析速度快并且占用内存少的xml解析器,非常适合android等移动设备,SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读取到的字符是否合法xml语法中的某部分,如果符合就会触发事件。

SAX解析流程:

3)  PULL解析技术

Android API 中,另外提供了Android.util.Xml 类,同样可以解析XML 文件,使用方法类似SAX,也都需编写Handler来处理XML 的解析,但是在使用上却比SAX 来得简单。它允许用户的应用程序代码从解析器中获取事件,这与SAX 解析器自动将事件推入处理程序相反。Pull解析器运行方式与SAX解析器类似,它提供了类似ide事件,如:开始元素和结束元素,使用parser.next()可以进入下一个元素并触发相应的事件。事件作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法获取一个Text类型的节点的值。

PULL解析流程:

三、 XML性能比较

  • 处理时间

  • 占用内存

四、 使用场景

DOM解析器,是通过将XML文档解析成树状模型并将其放入内存来完成解析工作的,而后对文档的操作都是在这个树状模型上完成的。这个在内存中的文档树将是文档实际大小的几倍。这样做的好处是结构清除、操作方便,而带来的麻烦就是极其耗费系统资源。

SAX解析器,正好克服了DOM的缺点,分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。

选择何种XML解析技术,取决于下面几个因素:

(1) 应用目的:如果打算对数据作出更改并将它输出为 XML,那么在大多数情况下,DOM 是适当的选择。并不是说使用 SAX和PULL 就不能更改数据,但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。

(2) 数据容量: 对于大型文件,SAX和PULL 是更好的选择。

(3) 数据使用:如果只有数据中的少量部分会被使用,那么使用 SAX,PULL来将该部分数据提取到应用程序中可能更好。另一方面,如果您知道自己以后会回头引用已处理过的大量信息,那么 SAX,PULL也许不是恰当的选择。

(4) 速度需要: SAX,PULL实现通常要比 DOM 实现更快。

(5) 添加节点:为了能动态给xml添加节点,推荐使用DOM。

(6) 在SAX和PULL都可以使用的情况下,建议使用PULL来解析。

五、 总结

对于Android 的移动设备而言,因为设备的资源比较宝贵,内存是有限的,所以我们需要选择适合的技术来解析XML,这样有利于提高访问的速度。

(1) DOM 在处理XML 文件时,将XML 文件解析成树状结构并放入内存中进行处理。当XML 文件较小时,我们可以选DOM,因为它简单、直观。

(2) SAX 则是以事件作为解析XML 文件的模式,它将XML 文件转化成一系列的事件,由不同的事件处理器来决定如何处理。XML 文件较大时,选择SAX 技术是比较合理的。虽然代码量有些大,但是它不需要将所有的XML 文件加载到内存中。这样对于有限的Android 内存更有效,而且Android 提供了一种传统的SAX 使用方法以及一个便捷的SAX 包装器。使用Android.util.Xml 类。

(3) PULL解析并未像SAX 解析那样监听元素的结束,而是在开始处完成了大部分处理。这有利于提早读取XML 文件,可以极大的减少解析时间,这种优化对于连接速度较慢的移动设备而言尤为重要。对于XML 文档较大但只需要文档的一部分时,PULL解析器则是更为有效的方法。

参考推荐:

XML 标准概览(IBM)

Android实现XML解析技术

Android系统中XML解析方案的选择

Android平台上的XML解析技术分析

W3C

W3C Schools(英文)

W3C Schools(中文)

抱歉!评论已关闭.