DOM解析器的接口已经被W3C标准化了。org.w3.dom包包含了接口类型的定义,比如:
Document和Element等。不同的提供者,比如Apache Organization和IBM都编写了实现这些接口的DOM解析器。SUN公司的XML处理JAVA API(Java API for XML Processing,JAXP)
库实际上可以插入到这些解析器中的任意一个中。但是SUN公司也在JAVA SDK中包含了自己的DOM解析器。在本文中我使用的就是JAVA的解析器。
1:要读入一个XML文档,首先要一个DocumentBuilder对象,可以这样得到:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
2:现在可以从文件中去读取一个XML文件了(文件路径:"F:""employees.xml")
得到XML文件有三种方式:
1:通过文件方式读取:
File file=new File("F:""employees.xml");
Document doc=builder.parse(file);
2:通过一个URL方式读取:
URL u=new URL("http://java.sun.com/index.html")
Document doc=builder.parse(u);
3:可以能过java IO 流的读取:
FileInputStream inputstream = new FileInputStream(
"F:""employees.xml");
Document doc=builder.parse(inputstream);
这里就写这么多了,在详细的请自己去查查阅资料。
下边是employees.xml 这个XML文件的内容:
<?xml version="1.0" encoding="GBK"?>
<employees>
<employee email="zzzlyr@163.com">
<name>李明</name>
<sex>女孩子</sex>
<age>30</age>
</employee>
<employee email="zzzlyr112@163.com">
<name>张钊钊</name>
<sex>男</sex>
<age>28</age>
</employee>
</employees>
publicvoid parseXml(String fileName) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(fileName);
// 1.获得文档根元素对对象;
Element root = document.getDocumentElement();
// 获得文档根元素下一级子元素所有元素;
NodeList nodeList = root.getChildNodes();
System.out.println(root.getNodeName());
if (null != root) {
for (int i = 0; i < nodeList.getLength(); i++) {
Node child = nodeList.item(i);
// 输出child的属性;
System.out.println(child);
// if (child.getNodeType() == Node.ELEMENT_NODE) {
// System.out.println(child.getAttributes().getNamedItem(
// "email").getNodeValue());
// }
//
// for (Node node = child.getFirstChild(); node != null; node = node
// .getNextSibling()) {
//
// if (node.getNodeType() == Node.ELEMENT_NODE) {
// if ("name".equals(node.getNodeName())) {
// System.out.println(node.getFirstChild()
// .getNodeValue());
// }
// }
// if (node.getNodeType() == Node.ELEMENT_NODE) {
// if ("sex".equals(node.getNodeName())) {
// System.out.println(node.getFirstChild()
// .getNodeValue());
// }
// }
// if (node.getNodeType() == Node.ELEMENT_NODE) {
// if ("age".equals(node.getNodeName())) {
// System.out.println(node.getFirstChild()
// .getNodeValue());
// }
// }
// }
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
我为了研究解析过程把写好的代码注释掉了,看这层输出结果:
employees
[#text:
]
[employee: null]
[#text:
]
[employee: null]
[#text:
]
第一个是整个文档的根元素名称,下边结果是第一层for输出结果,从结果可见而知
遍历了整个XML文件的所有子元素进行输出,如果不清楚可以和原XML文件对比可知
去掉注释部分结果如下:
employees
zzzlyr@163.com
李明
女孩子
30
zzzlyr112@163.com
张钊钊
男
28
从结果可知,DOM解析过程是先解析整个XML文件所有子元素,然后在能过第二个for
解析子元素下的子元素;
但是为什么第一个有类似于这样东西[#text:] 这是查了半天资料,原因是XML 文件元素之间的空白字符也是一个元素,<employees></employees>这之间空白;
child.getNodeType() == Node.ELEMENT_NODE代码可以忽略掉类似于这样东西;
这是解析,还有创建XML文档,自己看代码吧,我不多解释了;
整个代码:
package com.junhai.xml.test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
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;
import com.sun.org.apache.xerces.internal.util.XMLDocumentFilterImpl;
public class DomXmlDemo extends XMLDocumentFilterImpl implements XmlDocument {
private Document document;
public void init() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
this.document = builder.newDocument();
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
}
}
public void createXml(String fileName) {
this.init();
// 创建XML文件根节点;
Element root = this.document.createElement("employees");
this.document.appendChild(root);
// 创建XML文件根节点子节点;
Element employee = this.document.createElement("employee");
// 向根节点添加属性节点;
Attr email = this.document.createAttribute("email");
email.setNodeValue("zzzlyr@163.com");
// 把属性节点对象,追加到达根节点上去;
employee.setAttributeNode(email);
Element name = this.document.createElement("name");
// 向XML文件根节点子节点追加数据;
name.appendChild(this.document.createTextNode("李明"));
// 在把子节点的属性追加到子节点中元素中去;
employee.appendChild(name);
Element sex = this.document.createElement("sex");
sex.appendChild(this.document.createTextNode("女孩子"));
employee.appendChild(sex);
Element age = this.document.createElement("age");
age.appendChild(this.document.createTextNode("30"));
employee.appendChild(age);
root.appendChild(employee);
// 创建XML文件根节点子节点;
Element employee2 = this.document.createElement("employee");
// 向根节点添加属性节点;
Attr email2 = this.document.createAttribute("email");
email2.setNodeValue("zzzlyr2@163.com");
// 把属性节点对象,追加到达根节点上去;
employee2.setAttributeNode(email2);
Element name2 = this.document.createElement("name");
// 向XML文件根节点子节点追加数据;
name2.appendChild(this.document.createTextNode("张钊钊"));
// 在把子节点的属性追加到子节点中元素中去;
employee2.appendChild(name2);
Element sex2 = this.document.createElement("sex");
sex2.appendChild(this.document.createTextNode("男"));
employee2.appendChild(sex2);
Element age2 = this.document.createElement("age");
age2.appendChild(this.document.createTextNode("28"));
employee2.appendChild(age2);
root.appendChild(employee2);
TransformerFactory tf = TransformerFactory.newInstance();
try {
Transformer transformer = tf.newTransformer();
// Transformer transformer1=tf.newTransformer(Source source);
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
try {
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
StreamResult result = new StreamResult(pw);
transformer.transform(source, result);
System.out.println("生成XML文件成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("文件没有找到!");
} catch (TransformerException e) {
e.printStackTrace();
System.out.println("生成XML文件失败!");
}
} catch (TransformerConfigurationException e) {
e.printStackTrace();
}
}
public void parseXml(String fileName) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(fileName);
// 1.获得文档根元素对对象;
Element root = document.getDocumentElement();
// 获得文档根元素下一级子元素所有元素;
NodeList nodeList = root.getChildNodes();
System.out.println(root.getNodeName());
if (null != root) {
for (int i = 0; i < nodeList.getLength(); i++) {
Node child = nodeList.item(i);
// 输出child的属性;
//System.out.println(child);
if (child.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(child.getAttributes().getNamedItem(
"email").getNodeValue());
}
for (Node node = child.getFirstChild(); node != null; node = node
.getNextSibling()) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
if ("name".equals(node.getNodeName())) {
System.out.println(node.getFirstChild()
.getNodeValue());
}
}
if (node.getNodeType() == Node.ELEMENT_NODE) {
if ("sex".equals(node.getNodeName())) {
System.out.println(node.getFirstChild()
.getNodeValue());
}
}
if (node.getNodeType() == Node.ELEMENT_NODE) {
if ("age".equals(node.getNodeName())) {
System.out.println(node.getFirstChild()
.getNodeValue());
}
}
}
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
DomXmlDemo dom = new DomXmlDemo();
dom.createXml("F:\\employees.xml");
dom.parseXml("F:\\employees.xml");
}
}
结果如下:
生成XML文件成功!
employees
zzzlyr@163.com
李明
女孩子
30
zzzlyr2@163.com
张钊钊
男