Java中解析XML的工具很多,像JDOM,DOM4J等,但Java标准库提供的两种解析XML文档解析器是:DOM(Document Object Module)解析器 和 SAX(Simple API for XML)解析器。DOM解析器会读入整个XML文档并转换成树结构;SAX解析器会在读入XML文档时生成相应的事件;故也常叫基于文档对象模型的XML解析和基于事件驱动的XML解析;那它们有什么区别呢? 

   DOM解析器会读入整个文档,构建一个驻留在内存中的树型结构,我们就可以使用 DOM 接口来操作这个文档树,其优点是整个文档树在内存中,便于操作,支持删除、修改、重新排列等多种功能;缺点是需将整个文档读入内存中,在文档大时会消耗大量内存; 

   SAX解释器在XML文档读入时能够立即开始,而不是等待所有的数据加载完后处理,解析器通过发现元素开始、元素结束、文本开始、文档结束等来发送事件,通过种基于回调机制的方法来处理数据;其优点是解析速度快,不用事先调入整个文档,占用资源少;其缺点是必须实现事件处理程序,不能修改文档,不能随机访问。 

   DOM4J性能最好,连Sun的JAXM也在用DOM4J.目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J. 

    我们就细细的研究这几种方式吧。主要有4种:DOM、SAX、JDOM、JAXB


1.  DOM(Document Object Model)


 此 方法主要由W3C提供,它将xml文件全部读入内存中,然后将各个元素组成一棵数据树,以便快速的访问各个节点 。 因此非常消耗系统性能 ,对比较大的文档不适宜采用DOM方法来解析。 DOM API 直接沿袭了 XML 规范。每个结点都可以扩展的基于 Node 的接口,就多态性的观点来讲,它是优秀的,但是在 Java 语言中的应用不方便,并且可读性不强,著名的SPRING框架就是采用此方法读取XML。

首先来了解点Java DOM 的 API:
1.解析器工厂类:DocumentBuilderFactory

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

解析器:DocumentBuilder

DocumentBuilder db = dbf.newDocumentBuilder();

文档树模型Document

 Document doc = db.parse("bean.xml");  b.将需要解析的xml文档转化为输入流 InputStream is = new FileInputStream("bean.xml");

 Document doc = db.parse(is);

Document对象代表了一个XML文档的模型树,所有的其他Node都以一定的顺序包含在Document对象之内,排列成一个树状结构,以后对XML文档的所有操作都与解析器无关,

直接在这个Document对象上进行操作即可;

 包含的方法:


java 更快的xml解析 java xml解析工具_Java


java 更快的xml解析 java xml解析工具_Java_02


java 更快的xml解析 java xml解析工具_System_03

节点列表类NodeList

NodeList代表了一个包含一个或者多个Node的列表,根据操作可以将其简化的看做为数组


java 更快的xml解析 java xml解析工具_Java_04

节点类Node

Node对象是DOM中最基本的对象,代表了文档树中的抽象节点。但在实际使用中很少会直接使用Node对象,而是使用Node对象的子对象Element,Attr,Text等

元素类Element

是Node类最主要的子对象,在元素中可以包含属性,因而Element中有存取其属性的方法


java 更快的xml解析 java xml解析工具_java 更快的xml解析_05


java 更快的xml解析 java xml解析工具_XML_06

Node.getNamespaceURI() 返回和给定节点关联的名称空间字符串,如果该元素或属性没有关联的名称空间则返回 null。

属性类Attr

因为Attr并不是DOM树的一部分

基本的知识就到此结束,更加具体的大家可以参阅JDK API文档



 实例:

 


java 更快的xml解析 java xml解析工具_XML_07



1. import
2. //XML解析器接口 
3. import
4. //XML的DOM实现 
5. import
6. //写XML文件,很明显该类是一个单例,先获取产生DocumentBuilder工厂的工厂,在通过这个工厂产生一个DocumentBuilder,  
7. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
8. //允许名字空间
9. true);  
10. //允许验证
11. true);  
12. //获得DocumentBuilder的一个实例
13. try
14.  DocumentBuilder builder = factory.newDocumentBuilder();  
15. } catch
16. System.err.println(pce);  
17. //  出异常时输出异常信息,然后退出,下同
18. System.exit(1);  
19. }   
20. //解析文档,并获得一个Document实例。 
21. try
22. //Document可以看作是XML在内存中的一个镜像,那么一旦获取这个Document 就意味着可以通过对 
23. //内存的操作来实现对XML的操作,首先第一步获取XML相关的Document
24. Document doc = builder.parse(fileURI);  
25. } catch
26. System.err.println(dom.getMessage());  
27. System.exit(1);  
28. } catch
29. System.err.println(ioe);  
30. System.exit(1);       
31. }  
32. //获得根节点StuInfo,在xml文件里,只有一个根元素,先把根元素拿出来看看  
33. Element elmtStuInfo = doc.getDocumentElement();  
34. //得到所有student节点
35.  NodeList nlStudent = elmtStuInfo.getElementsByTagNameNS(  
36. "student");  
37. for
38. //当前student节点元素
39.      Element elmtStudent = (Element)nlStudent.item(i);  
40.      NodeList nlCurrent =              elmtStudent.getElementsByTagNameNS(  
41. "name");  
42. }


 对于读取得方法其实是很简单的,写入xml文件也是一样不复杂。

 

 


java 更快的xml解析 java xml解析工具_XML_07



1. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();   
2. DocumentBuilder builder = null;   
3. try
4. builder = factory .newDocumentBuilder();   
5. } catch
6. System.err.println(pce);   
7. System.exit(1);   
8. }  
9. Document doc = null;   
10. doc = builder .newDocument();  
11. //下面是建立XML文档内容的过程,
12. //先建立根元素"学生花名册" 
13. Element root = doc.createElement("学生花名册");   
14. //根元素添加上文档 
15. doc.appendChild(root);   
16. //建立"学生"元素,添加到根元素 
17. Element student = doc.createElement("学生");   
18. student.setAttribute("性别", studentBean.getSex());   
19. root.appendChild(student);   
20. //建立"姓名"元素,添加到学生下面,下同 
21. Element name = doc.createElement("姓名");   
22. student.appendChild(name);   
23. Text tName = doc.createTextNode(studentBean.getName());   
24. name.appendChild(tName);  
25. Element age = doc.createElement("年龄");   
26. student.appendChild(age);   
27. Text tAge = doc.createTextNode(String.valueOf(studentBean.getAge()));   
28. age.appendChild(tAge);


2.SAX (Simple API for XML) 

 

 

此方法主要由XML-DEV 邮件列表的成员开发的,SAX是基于事件的方法,它很类似于标签库的处理机制,在标签开始、结束以及错误发生等等地方调用相应的接口实现方法,不是全部文 档都读入内存。 SAX具有优异的性能和利用更少的存储空间特点。SAX 的设计只考虑了功能的强大性,却没有考虑程序员使用起来是否方便。

使用必须扩展ContentHandler、ErrorHandler、DTDHandler等,但是必须扩展ContentHandler(或者DefaultHandler )。

 


java 更快的xml解析 java xml解析工具_XML_07



1. import
2. public  class  MyContentHandler implements
3.   … …  
4. }  
5. /**
6.      * 当其他某一个调用事件发生时,先调用此方法来在文档中定位。
7.      * @param locator
8.      */
9. public void
10.     }  
11. /**
12.      * 在解析整个文档开始时调用
13.      * @throws SAXException
14.      */
15. public void startDocument() throws
16. "** Student information start **");  
17.     }  
18. /**
19.      * 在解析整个文档结束时调用
20.      * @throws SAXException
21.      */
22. public void endDocument() throws
23. "**** Student information end ****");  
24.     }  
25. /**
26.      * 在解析名字空间开始时调用
27.      * @param prefix
28.      * @param uri
29.      * @throws SAXException
30.      */
31. public void
32. throws
33.     }  
34. /**
35.      * 在解析名字空间结束时调用
36.      * @param prefix
37.      * @throws SAXException
38.      */
39. public void endPrefixMapping(String prefix) throws
40.     }  
41. /**
42.      * 在解析元素开始时调用
43.      * @param namespaceURI
44.      * @param localName
45.      * @param qName
46.      * @param atts
47.      * @throws SAXException
48.      */
49. public void
50. throws
51.     }  
52. /** 在解析元素结束时调用
53.      * @param namespaceURI
54.      * @param localName 本地名,如student
55.      * @param qName 原始名,如LIT:student
56.      * @throws SAXException   */
57. public void endElement(String namespaceURI, String localName,String qName) throws
58. if
59. ":"+currentData);  
60.         }  
61. }


取得元素数据的方法——characters

 

取得元素数据中的空白的方法——ignorableWhitespace
在解析到处理指令时调用的方法——processingInstruction
当未验证解析器忽略实体时调用的方法——skippedEntity
运行时,只需要使用下列代码:

 


java 更快的xml解析 java xml解析工具_XML_07



  1. MySAXParser mySAXParser = new
  2. mySAXParser.parserXMLFile("SutInfo.xml");  


 3.JDOM

 

JDOM的处理方式有些类似于DOM,但它主要是用SAX实现的 。JDOM用Java的数据类型来定义操作数据树的各个节点 。JDOM的性能也很优越。

 


java 更快的xml解析 java xml解析工具_XML_07



1. import
2. import
3. import
4. SAXBuilder builder = new SAXBuilder(false);  
5. //得到Document
6. Document doc = builder.build(fileURI);  
7. //名字空间
8. Namespace ns = Namespace.getNamespace("LIT" , "http://www.lit.edu.cn/student/ ");  
9. //取得所有LIT:student节点的集合
10. List lstStudents = elmtStuInfo.getChildren("student",ns);  
11. for
12.  Element elmtStudent = (Element)lstStudents.get(i);  
13. "name", ns);  
14. }  
15. //修改
16. elmtLesson.getChild("lessonScore" , ns).setText("100");  
17. //删除
18. elmtStuInfo.removeChild("master", ns);  
19. //添加
20. elmtStuInfo.addContent(new Element("master" , ns).addContent(new Entity("masterName")));  
21. //输出文档
22. //第一个参数是缩进字符串,这里是4个空格。
23. //第二个参数是true,表示需要换行。
24. XMLOutputter printDoc = new XMLOutputter(" ", true);  
25. new FileOutputStream("StuInfo.xml"));


4.JAXB (Java And XML Binding)

 

 

JAXB 是以SUN为主的一些公司公布的。JAXB将schema(或者DTD)映射为java对象(.java文件),然后使用这些java对象来解析xml文件。需要使用之前生成java文件,因而要有固定的schema,无法处理动态的xml文件。

首先使用xjc命令,生成java文件
xjc  [-options ...]

(生成的文件较多)


java 更快的xml解析 java xml解析工具_XML_07



1. JAXBContext jc = JAXBContext.newInstance(“packageName");  
2.  Unmarshaller unmarshaller = jc.createUnmarshaller();  
3. Collection collection= (Collection)unmarshaller.unmarshal(new File( "books.xml"));  
4. CollectionType.BooksType booksType =collection.getBooks();  
5. List bookList = booksType.getBook();  
6. for( … ){  
7.  test.jaxb.BookType book =(test.jaxb.BookType) bookList.get(i);  
8. "Book Name: "
9. "Book ISBN: "
10. }


 

 

补充另一种方法:

 

据悉dom4j在xml解析方面是性能最好的,hibernate等框架都使用它作为解析的工具。

 

解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要加入包jaxen-1.1-beta-7.jar

 

 

写了简单的dom4j的使用的demo,以备回忆,有些是dom4j的文挡里例子改编的 
使用dom4j解析下面的xml文件。

 


java 更快的xml解析 java xml解析工具_XML_07



1. <?xml version="1.0" encoding="GB2312"?>
2.   
3. <?xml-stylesheet type="text/xsl" href="students.xsl"?>
4.   
5. <students>
6. <student sn="01">
7. <name>张三</name>
8. <age>18</age>
9. </student>
10.       
11. <student sn="02">
12. <name>李四</name>
13. <age>20</age>
14. </student>
15. </students>


 

Parse.java 


java 更快的xml解析 java xml解析工具_XML_07


1. import
2.   
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10.   
11. public class
12.   
13. public static void
14. new
15. new File("src/students.xml");  
16. try
17.             Document doc = reader.read(file);  
18. new
19. catch
20. // TODO Auto-generated catch block
21.             e.printStackTrace();  
22.         }  
23.     }  
24.   
25. public static class MyVistor extends
26. public void
27. "Attibute:---" + node.getName() + "="+ node.getValue());  
28.         }  
29.   
30. public void
31. if
32. "Element:---" + node.getName() + "="
33.                         + node.getText());  
34. else{  
35. "--------" + node.getName() + "-------");  
36.             }  
37.         }  
38.   
39. @Override
40. public void
41. "PI:"+node.getTarget()+" "+node.getText());  
42.         }  
43.     }  
44. }


使用dom4j来将属性写入xml 


java 更快的xml解析 java xml解析工具_XML_07


1. import
2. import
3.   
4. import
5. import
6. import
7. import
8. import
9.   
10. public class
11.   
12. public static void
13. // TODO Auto-generated method stub
14. try
15. new XMLWriter(new FileWriter("src/author.xml"));  
16.             Document doc = createDoc();  
17.             writer.write(doc);  
18.             writer.close();  
19.   
20. // Pretty print the document to System.out
21. // 设置了打印的格式,将读出到控制台的格式进行美化
22.             OutputFormat format = OutputFormat.createPrettyPrint();  
23. new
24.             writer.write(doc);  
25.   
26. catch
27. // TODO Auto-generated catch block
28.             e.printStackTrace();  
29.         }  
30.     }  
31.   
32. public static
33.         Document doc = DocumentHelper.createDocument();  
34. "root");  
35. "author").addAttribute("name",  
36. "Kree").addAttribute("location", "UK")  
37. "Kree Strachan");  
38. "author").addAttribute("name", "King")  
39. "location", "US").addText("King McWrirter");  
40. return
41.     }  
42. }


使用dom4j写入到author.xml文件的内容


java 更快的xml解析 java xml解析工具_XML_07


1. <?xml version="1.0" encoding="UTF-8"?>  
2. <root>  
3. <author name="Kree" location="UK">Kree Strachan</author>  
4. <author name="King" location="US">King McWrirter</author>  
5. </root>