java-工具-XML解析工具对比

本文涉及的产品
云解析DNS,个人版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: -------------------------------------SAX解析xml---------------------------------- 》Sax定义          SAX是一个解析速度快并且占用内存少的xml解析器,...

-------------------------------------SAX解析xml----------------------------------

》Sax定义

         SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于android等移动设备

         SAX全称是Simple API for Xml,既是指一种接口,也是一个软件包

         作为接口,sax是事件驱动型xml解析的一个标准接口

》Sax特点

        1. 解析效率高,占用内存少

        2.可以随时停止解析

        3.不能载入整个文档到内存

        4.不能写入xml

        5.SAX解析xml文件采用的是事件驱动

        ---sax并不需要解析完 整个文档,在按内容顺序解析文档的过程中,sax会判断当前读到的字符是否合法xml语法中的某部分,如果符合就会触发事件

》Sax工作原理

         Sax的工作原理简单的说,就是对文档进行顺序扫描,扫描到文档(document)开始与结束,扫描到元素(element)开始、结束等地方时调用事件处理

         处理函数做相应动作,然后继续扫描,直到文档结束。

》Sax解析文档过程

           1.继承DefaultHandler  ,并实现方法       

           2.创建SAX解析器工厂

           3.获得解析器

           4.获得输入流

           5.使用输入流,和实现接口作参数,调用解析器的解析方法进行解析

 

》defaultHandler 接口是实现contentHandler接口

         ContentHandler接口中的常用方法

                 >startDocument()

                            当遇到文档开头的时候,调用这个方法,可以在其中做一些与准备工作

                 >endDocument()

                             当文档结束的时候,调用这个方法,可以在其中做一些善后工作

                 >startElement(String namespaceURL, String localName, String qName, Attributes atts)

                             当读到一个开始标签的时候,会触发这个方法。namespaceURL就是命名空间,localName是不带命名空间前缀的标签名,

                             qName是待命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。

                 >endElement(String uri, String localName, String name)

                            当遇到结束标签的时候,调用这个方法

                  >characters(char[] ch, int start, int length)

                            这个方法用来处理在xml文件中读到的内容,第一个参数为文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,

                            使用new String(ch, start, length)就可以获取内容

 

》SAX解析实例

          -------------1.在src下创建xml 文件,并结合成实体类Userinfo.java-------------

<?xml version="1.0" encoding="UTF-8"?>
<admins>
<admin id="1">
<name>阿龙</name>
<age>23</age>
<sex>男</sex>
<email>along@qq.com</email>
</admin>
</admins>

 

          ----------Userinfo.java----

        String name;
int age;
String sex;
String email;
String id;

      。。。  生成get、set方法

     --------------------2.创建XmlPaser继承defaultHandler----------------------

  public class XmlPaser extends DefaultHandler{

        //创建user对象为把查到的内容放到里面

        Userinfo user; 
public Userinfo getUser() {
return user;
}
public void setUser(Userinfo user) {
this.user = user;
}

         //定义标签变量

        String tagName = null;

        //开始文档处理些准备工作

         public void startDocument() throws SAXException { 
user = new Userinfo();
super.startDocument();
}

       

        //读到第一个标签触发

         public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
tagName = localName;
if("admin".equals(tagName)){
user.setId(attributes.getValue(0));
System.out.println("id:  "+attributes.getValue(0));
}
}

        

       //读取文本内容

      public void characters(char[] ch, int start, int length)
throws SAXException {
if(tagName!=null){
if("name".equals(tagName)){
String str = new String(ch,start,length);
user.setName(str); 
System.out.println("name:  "+str);
}else if("age".equals(tagName)){
String str = new String(ch,start,length);
user.setAge(Integer.parseInt(str));
System.out.println("age:   "+str);
}else if("sex".equals(tagName)){
String str = new String(ch,start,length);
user.setSex(str);
System.out.println("sex:  "+str);
}else if("email".equals(tagName)){
String str = new String(ch,start,length);
user.setEmail(str);
System.out.println("email:  "+str); 
}
}
}

        //遇到结束标签

       public void endElement(String uri, String localName, String qName)
throws SAXException { 
tagName=null;

}

        //文档读完

public void endDocument() throws SAXException { 
super.endDocument();
}

 }

 

----------------布局文件main省略-----------

----------------------3.-类SAXActivity继承Activity----------------

         Button btnOk;

        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

btnOk = (Button)this.findViewById(R.id.button1);
        btnOk.setOnClickListener(new OnClickListener() {

public void onClick(View v){

//创建解析工厂和解析器

                        SAXParserFactory spf = SAXParserFactory.newInstance();

                        try{

SAXParser sp = spf.newSAXParser();

                                //解析

                               XmlPaser xp = new XmlPaser();

                                InputStream is = this.getClass().getClassLoader().getResourceAsStream("user.xml");

sp.parse(is,xp);

 

//获得读取到的内容

                                 Userinfo user = xp.getUser();

//在页面显示

.................

}

}

       });

     }

 

---------------------------------------Dom解析Xml--------------------------------------------

》DOM简介

        dom全称Document Object Model ,为xml文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个主流内存的树结构,

         然后代码就可以使用dom接口来操作这个树结构

》DOM的特点

         >优点

                  1.整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能

                  2.通过树形结构存取xml文档

                  3.可以在树的某个节点上向前或向后移动

           >缺点

                  1.将整个文档调入内存(包括无用的节点),浪费时间和空间

            >适用场合

                  一旦解析了文档还需多次访问这些数据;硬件资源充足(内存,cpu)

》DOM解析步骤

      1.创建解析器工厂

      2.获得解析器工厂

      3.接受一个xml文档作为输入参数名,并得到一个xml的文档对象(Document)

      4.操作文档对象

 

》解析实例:

-----------------------1.创建要解析的xml文件、和实体类(Person)---------------------------

<?xml version="1.0" encoding="utf-8"?>
<users>
<user id="1">
<name>Tom</name>
<age>19</age>
</user>
<user id="2">
<name>Jaary</name>
<age>18</age>
</user>
</users>

 

实体类 略

-----------------------2. Dom解析(DomService.java)-----------------------------------

public List<Person> getPersons(InputStream input) throws Throwable{

//获得解析器工厂

         DocumentBuilderFactory    factory = DocumentBuilderFactory.newInstance();

         //获得解析器

          DocumentBuilder builder = factory.newDocumentBuilder();

        //进行解析

         Document  doc = builder.parse(input);

 

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

       //获得所有叫user的节点

        NodeList  list = doc.getElementsByTagName(user);

        String id="";
String name="";
String age="";
for(int i=0;i<list.getLength();i++){
//取得第i个user节点
Element node=(Element)list.item(i);
Person p=new Person();
//获取id属性
id=node.getAttribute("id");
//获得user节点下的子节点列表
NodeList userList=node.getChildNodes();
for(int j=0;j<userList.getLength();j++){
//判断是否是元素节点,name和age属于元素节点
if(userList.item(j).getNodeType()==Node.ELEMENT_NODE){

Element childNode=(Element)userList.item(j);
if("name".equals(childNode.getNodeName())){
name=childNode.getFirstChild().getNodeValue();
}
else if("age".equals(childNode.getNodeName())){
age=childNode.getFirstChild().getNodeValue();
}
p.setName(name);
p.setAge(age);
p.setId(Integer.parseInt(id));
}

}

personList.add(p);
}
return personList;

}

-------------------------3.Activity01继承Activity类----------------------------------------------------

 

 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        InputStream is=this.getClass().getClassLoader().getResourceAsStream("test.xml");
        DomService dom=new DomService();
        
        try {
List<Person> ps=dom.getPersons(is);
for(Person p:ps){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
} catch (Exception e) { 
e.printStackTrace();
}
    }

 

--------------------------------------pull解析-----------------------------

》pull解析器简介

        1.pull解析器是android内置的解析器,解析原理与sax类似

        2.pull它提供了类似的事件。

              如:开始元素和结束元素事件,使用parse.next()可以进入下一个元素并触发相应的事件,事件将作为数值代码被发送

                      因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法获取下一个Text类型节点的值 

 

》pull与sax的不同之处

          1.pull读取xml文件后触发相应的事件调用方法返回的是数字。

          2.pull可以在程序中控制,想解析到哪里就可以停止到哪里

          3.Android中更推荐使用pull解析

 

》pull解析步骤

      1.创建解析器对象

          XmlPullParser paser = Xml.newPullParser();

      2.进行解析

             paser.setInput(input,"utf-8");

      3.产生第一个解析事件

              int eventType = paser.getEventType();

       4.可以使用循环判断是否继续解析

                while(eventType!=XmlPullParser.END_DOCUMENT){}

 

 

 

 

》解析实例

-------------------1。创建xml.及实例对象(Person.java)----------------略

--------------------2.pull解析(PullService .java)----------------------

List<Person> getAlPerson(InputStream is) throws XmlPullParserException, IOException{

List<Person> persons=null;
Person p=null;
XmlPullParser parser=Xml.newPullParser();
parser.setInput(is,"utf-8");
//获得事件类型
int type=parser.getEventType();
while(type!=XmlPullParser.END_DOCUMENT){

switch(type){

case XmlPullParser.START_DOCUMENT://文档开始
persons=new ArrayList<Person>();
break;
case XmlPullParser.START_TAG://元素开始
if(parser.getName().equals("user")){

p=new Person();
String id=parser.getAttributeValue(0);
p.setId(Integer.parseInt(id));
}
else if(parser.getName().equals("name")){
if(p!=null){

String name=parser.nextText();
p.setName(name);
}
}
else if(parser.getName().equals("age")){

String age=parser.nextText();
p.setAge(age);
}
break;
case XmlPullParser.END_TAG:
if("user".equals(parser.getName())){

persons.add(p);
p=null;
}
break;

}
type=parser.next();
}
return persons;
}
}

------------------------------------Activity类-----------------------------------

 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        InputStream is=this.getClass().getClassLoader().getResourceAsStream("test.xml");
        PullService pps=new PullService();
        
        try {
List<Person> ps=pps.getPersons(is);
for(Person p:ps){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    }

 

SAX、DOM、PULL的比较

SAX、DOM、PULL各有自己的特点,具体操作XML的时候该如何选择呢?

1.内存占用

这是一个根本性问题。由于Android手机性能相对于现在的应用操作还是有限的,程序对内存的占用直接影响到了解析XML的速度。在这点上,SAX、Pull以它们比DOM占用更少的内存的解析方式,更适合于Android手机开发。

2.编程方式

SAX采用事件驱动,在相应事件触发的时候,会调用用户编写好的方法。也就是说,每解析一类XML,就要编写一个新的适合该类XML的处理类。这显然不是一个好的解决办法,尽管其在解析速度上是那么优秀。而这点,DOM因为是W3C的规范。所以被更多程序员所知道和使用。所以在开发过程中,没有太大困难。Pull虽然属于一个小众的,甚至是不为人知的解析器,但是通过上面对其介绍和示例,我们应该能看出它的简洁性。

3.访问与修改

由于采用的是流式解析,这就说明它们不能像DOM那样随机访问,XML的其中任意一个节点。并且,SAX并没有提供对文档中加节点的API,更没有删除,修改文档内容的方法。

4.访问方式

这是产生它们解析快慢的根本原因。如果把SAX和Pull比喻成一目十行,很快但是是走马观花的阅读方式的话,那么DOM就是逐字逐句的阅读,很慢,但是是过目不忘。这里还要需要注意的是,SAX,Pull解析的方式是同步的,即解析器读到哪里,就对哪里进行处理。而DOM是已经将文件解析好后,供用户提取XML中感兴趣的信息。

总结:

出于对内存占用的考虑,推荐使用SAX或者Pull来工作。可是根据它们工作的原理:如果只是需要XML最后的几个节点的相关信息,或者出现反复检索XML文件的情况。那么基本上三者在性能上就没有什么差异,反而在这时,SAX的处理类会使程序显得比其他的实现方式显得臃肿。所以,想做一个高性能的Android软件,还是要多分析,选择合适的工具,才能发挥它的作用。

目录
相关文章
|
1天前
|
XML Web App开发 JavaScript
XML DOM 解析器
Most browsers have a built-in XML parser that converts XML into a JavaScript accessible object (XML DOM).
|
1天前
|
XML Web App开发 JavaScript
XML DOM 解析器
解析器把 XML 转换为 JavaScript 可存取的对象(XML DOM)。
|
3天前
|
安全 Java 数据处理
Java并发编程:线程同步与协作的深度解析
在探索Java并发编程的海洋中,线程同步与协作的灯塔指引着航向。本文将深入挖掘线程同步机制的核心原理,揭示锁、条件变量等工具如何确保数据的一致性和线程间有序的通信。通过案例分析,我们将解码高效并发模式背后的设计哲学,并探讨现代Java并发库如何简化复杂的同步任务。跟随文章的步伐,您将获得提升多线程应用性能与可靠性的关键技能。 【7月更文挑战第24天】
17 5
|
4天前
|
Java 关系型数据库 开发工具
Java开发者必备技能与工具:构建高效开发环境的指南
【7月更文挑战第23天】作为Java开发者,掌握核心技能、熟练使用开发工具与框架、不断提升自己的软技能是构建高效开发环境的关键。希望本文能够为广大Java开发者提供一些有价值的参考和启示,助力大家在Java开发的道路上越走越远。
|
4天前
|
缓存 安全 算法
Java内存模型深度解析与实践应用
本文深入探讨Java内存模型(JMM)的核心原理,揭示其在并发编程中的关键作用。通过分析内存屏障、happens-before原则及线程间的通信机制,阐释了JMM如何确保跨线程操作的有序性和可见性。同时,结合实例代码,展示了在高并发场景下如何有效利用JMM进行优化,避免常见的并发问题,如数据竞争和内存泄漏。文章还讨论了JVM的垃圾回收机制,以及它对应用程序性能的影响,提供了针对性的调优建议。最后,总结了JMM的最佳实践,旨在帮助开发人员构建更高效、稳定的Java应用。
|
4天前
|
安全 Java 编译器
Java内存模型深度解析
【7月更文挑战第23天】在探索Java的高效与稳定性之谜时,我们不可避免地要深入其核心——Java内存模型(JMM)。本文将揭开JMM的神秘面纱,从基本概念到底层实现机制,再到并发编程中的应用实践,全面剖析这一确保Java程序正确性的基石。通过理解JMM的设计哲学和运作原理,开发者能够更好地编写出既高效又线程安全的代码,避免那些隐藏在多线程环境下的陷阱。
|
4天前
|
XML Web App开发 JavaScript
XML DOM 解析器
大多数浏览器内置XML解析器,将XML转化为JavaScript可访问的XML DOM对象。XML DOM提供遍历、访问、插入和删除节点的功能。文档须先加载至DOM。示例代码通过XMLHTTP请求加载`books.xml`,兼容多种浏览器,响应设置为XML DOM用于后续处理。
|
4天前
|
XML Web App开发 JavaScript
XML DOM 解析器
**XML DOM解析器将XML转换为JS对象,便于操作。浏览器内置XML解析器,通过XMLHttpRequest或ActiveXObject加载XML如&quot;books.xml&quot;。
|
2天前
|
存储 监控 算法
Java中的垃圾回收机制深度解析
在Java的内存管理中,垃圾回收机制(Garbage Collection, GC)扮演着至关重要的角色。本文将深入探讨Java垃圾回收的工作原理、常见的垃圾回收算法以及调优策略,旨在帮助开发者更好地理解和掌握这一核心机制,进而优化Java应用的性能表现。
13 0
|
2天前
|
XML Web App开发 JavaScript
XML DOM 解析器
Most browsers have a built-in XML parser to create an XML DOM object from XML, making it accessible via JavaScript. The XML DOM includes methods for navigating, accessing, inserting, and deleting nodes in the XML tree.

推荐镜像

更多