一、前言用Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOM。Sun公司提供了Java API for XML Parsing(JAXP)接口来使用SAX和DOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。

JAXP接口包含了三个包:

(1)org.w3c.dom W3C推荐的用于XML标准规划文档对象模型的接口。

(2)org.xml.sax  用于对XML进行语法分析的事件驱动的XML简单API(SAX)

(3)javax.xml.parsers解析器工厂工具,程序员获得并配置特殊的特殊语法分析器。

二、前提

DOM编程不要其它的依赖包,因为JDK里自带的JDK里含有的上面提到的org.w3c.dom、org.xml.sax 和javax.xml.parsers包就可以满意条件了。

三、使用DOM解析XML文档

我们现在来看看DOM是如何解析XML的吧!同样的,我将从一个简单的不能再简单的例子来说明DOM是如何解析XML文档的,先让我们看看XML是什么内容吧:

1. <?xml version="1.0" encoding="gb2312"?>
2. <books>
4. <name>JAVA思想</name>
5. <price>99.0</price>
6. </book>
7. </books>

 

 

简单的不能再简单了。但是该有的都有了,根元素、属性、子节点。好了,能反应问题就行了,下面来看看解析这个XML文件的Java代码吧!

1. import
2. import
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13.   
14. public class
15. public
16.         DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();  
17. try
18.             DocumentBuilder dombuilder=domfac.newDocumentBuilder();  
19. new FileInputStream("WebRoot/WEB-INF/hell.xml");  
20.             Document doc=dombuilder.parse(is);  
21.             Element root=doc.getDocumentElement();  
22.             NodeList books=root.getChildNodes();  
23. if(books!=null){  
24. for(int i=0;i<books.getLength();i++){  
25.                     Node book=books.item(i);  
26. if(book.getNodeType()==Node.ELEMENT_NODE){  
27. "email").getNodeValue();  
28.                         System.out.println(email);  
29. for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){  
30. if(node.getNodeType()==Node.ELEMENT_NODE){  
31. if(node.getNodeName().equals("name")){  
32.                                     String name=node.getNodeValue();  
33.                                     String name1=node.getFirstChild().getNodeValue();  
34.                                     System.out.println(name);  
35.                                     System.out.println(name1);  
36.                                 }  
37. if(node.getNodeName().equals("price")){  
38.                                     String price=node.getFirstChild().getNodeValue();  
39.                                     System.out.println(price);  
40.                                 }  
41.                             }  
42.                         }  
43.                     }  
44.                 }  
45.             }  
46. catch
47.             e.printStackTrace();  
48. catch
49.             e.printStackTrace();  
50. catch
51.             e.printStackTrace();  
52. catch
53.             e.printStackTrace();  
54.         }  
55.     }  
56. public static void
57.     {  
58. new
59.     }  
60.       
61. }

 

 

四、代码解释先看看这个程序引用类:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

//下面主要是org.xml.sax包的类

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

上面那么简单的代码一看就明白了,但是为了介绍个DOM编程的大概还是来看看这个程序吧:

(1)得到DOM解析器的工厂实例

DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();

得到javax.xml.parsers.DocumentBuilderFactory;类的实例就是我们要的解析器工厂

(2)从DOM工厂获得DOM解析器

DocumentBuilder dombuilder=domfac.newDocumentBuilder();

通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder()得到DOM解析器

(3)把要解析的XML文档转化为输入流,以便DOM解析器解析它

InputStream is=new FileInputStream("bin/library.xml");

InputStream是一个接口。

(4)解析XML文档的输入流,得到一个Document

Document doc=dombuilder.parse(is);

由XML文档的输入流得到一个org.w3c.dom.Document对象,以后的处理都是对Document对象进行的

(5)得到XML文档的根节点

Element root=doc.getDocumentElement();

在DOM中只有根节点是一个org.w3c.dom.Element对象。

(6)得到节点的子节点

NodeList books=root.getChildNodes();

for(int i=0;i<books.getLength();i++){

Node book=books.item(i);

}

这是用一个org.w3c.dom.NodeList接口来存放它所有子节点的,还有一种轮循子节点的方法,后面有介绍

(7)取得节点的属性值

String email=book.getAttributes().getNamedItem("email").getNodeValue();

System.out.println(email);

注意,节点的属性也是它的子节点。它的节点类型也是Node.ELEMENT_NODE

(8)轮循子节点

for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("name")){
String name=node.getNodeValue();

String name1=node.getFirstChild().getNodeValue();

System.out.println(name);

System.out.println(name1);

}

if(node.getNodeName().equals("price")){

String price=node.getFirstChild().getNodeValue();

System.out.println(price);
}

}

这段代码的打印输出为:

zhoujunhui@163.comnull
JAVA
99.0

从上面可以看出

String name=node.getNodeValue();  是一个空值。而

String name1=node.getFirstChild().getNodeValue(); 才是真正的值,这是因为DOM把<name>rjzjh</name>也当作是两层结构的节点,其父节点为<name>节点本身,且它只有一个子节点(如果有属性的话就不止一个了!),子节点是它的值“rjzjh”,所以我们看到上面的结果。

还有,子节点的节点类型也是Node.ELEMENT_NODE型的,node.getNextSibling()方法是取下一个相邻的节点。

五、DOM结点

DOM是一些节点的集合,由于文档中可能包含有不同类型的信息,所以定义了几种不同类型的节点。DOM中最常见的节点类型有:

(1)元素:

元素是XML的基本构件。元素的子节点可以是其它元素、文本节点或两者都有。元素节点还可以只含有属性这一唯一类型的节点。

(2)属性:

属性节点包含关于元素节点的信息,但它不是元素的子节点

(3)文本:

文本节点文本信息,或干脆是空白的文本。

(4)文档:

文档节点是整个文档中所有其它节点的父节点

元素是一种很重要的类型节点,元素节点可以是其他节点的容器。

六、String转XML的方法

一、使用最原始的javax.xml.parsers,标准的jdk api  
// 字符串转XML
String xmlStr = /"....../";  
StringReader sr = new
InputSource is = new
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
DocumentBuilder builder=factory.newDocumentBuilder();  
Document doc = builder.parse(is);  
//XML转字符串
TransformerFactory  tf  =  TransformerFactory.newInstance();  
Transformer t = tf.newTransformer();  
t.setOutputProperty(/"encoding/",/"GB23121/");//解决中文问题,试过用GBK不行
ByteArrayOutputStream  bos  =  new
t.transform(new DOMSource(doc), new
String xmlStr = bos.toString();  
  
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();   
  DocumentBuilder builder;  
try
   builder  =  factory.newDocumentBuilder();  
new
catch
//  TODO Auto-generated catch block 
    e.printStackTrace();  
catch
//  TODO Auto-generated catch block 
    e.printStackTrace();  
catch
//  TODO Auto-generated catch block 
    e.printStackTrace();  
  }   
这里的XML DOCUMENT为org.w3c.dom.Document  
  二、使用dom4j后程式变得更简单  
// 字符串转XML
String xmlStr = /"....../";  
Document document = DocumentHelper.parseText(xmlStr);  
// XML转字符串
Document document = ...;  
String text = document.asXML();  
  
SAXReader saxReader = new
        Document document;  
try
new
            Element incomingForm = document.getRootElement();  
catch
// TODO Auto-generated catch block
            e.printStackTrace();  
        }  
这里的XML DOCUMENT为org.dom4j.Document  
  三、使用JDOM  
JDOM的处理方式和第一种方法处理很类似  
//字符串转XML
String xmlStr = /"...../";  
StringReader sr = new
InputSource is = new
Document doc = (new
//XML转字符串
Format format = Format.getPrettyFormat();  
format.setEncoding(/"gb2312/");//配置xml文档的字符为gb2312,解决中文问题
XMLOutputter xmlout = new
ByteArrayOutputStream bo = new
xmlout.output(doc,bo);  
String xmlStr = bo.toString();  
这里的XML DOCUMENT为org.jdom.Document  
  四、JAVASCRIPT中的处理  
//字符串转XML
var xmlStr = /"...../";  
var xmlDoc = new ActiveXObject(/"Microsoft.XMLDOM/");  
xmlDoc.async=false;  
xmlDoc.loadXML(xmlStr);  
//能够处理这个xmlDoc了
var name = xmlDoc.selectSingleNode(/"/person/name/");  
alert(name.text);  
//XML转字符串
var xmlDoc = ......;  
var xmlStr = xmlDoc.xml  
这里的XML DOCUMENT为javascript版的XMLDOM