1.DOM简介
DOM树所提供的随机访问方式给应用程序带来了很大的灵活性,它可以任意地控制整个XML文档中的内容,然而,DOM分析器把整个XML文档转换文DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高,而且对于结构复杂的树的遍历也是一项耗时的操作。所以DOM分析器对机器性能要求较高,程序效率并不理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问带来的方便,因此DOM解析器还是有很广泛的应用。
2.DOM常用接口及API
在DOM解析当中有以下4个核心的接口:
- Document
- Node
- NodeList
- NamedNodeMap
1)Document : 此接口代表了整个XML文档,表示整颗DOM树的根,提供了对文档中的数据进行访问和操作的入口,通过Document节点可以访问XML文件中所有的元素内容。
Document接口的常用方法:
方法返回值 | 方法定义 | 方法含义 |
---|---|---|
NodeList | getElementsByTagName(String tagname) | 按文档顺序返回包含在文档中且具有给定标记名称的所有 Element 的 NodeList。 |
Element | createElement(String tagName) | 创建指定类型的元素。 |
Text | createTextNode(String data) | 创建给定指定字符串的 Text 节点。 |
Attr | createAttribute(String name) | 创建给定名称的 Attr。 |
2)Node:此接口在整个DOM树中具有举足轻重的地位,DOM操作的核心接口中有很大一部分接口是从Node接口继承过来的,例如Document、Element、Attr等接口,在DOM树中,每一个Node接口代表树中的一个节点。
Node接口的常用方法:
方法返回值 | 方法定义 | 方法含义 |
---|---|---|
Node | appendChild(Node newChild) | 将节点 newChild 添加到此节点的子节点列表的末尾。 |
NodeList | getChildNodes() | 包含此节点的所有子节点的 NodeList。 |
Node | getFirstChild() | 此节点的第一个子节点。 |
Node | getLastChild() | 此节点的最后一个节点。 |
boolean | hasChildNodes() | 返回此节点是否具有任何子节点。 |
boolean | hasAttributes() | 返回此节点(如果它是一个元素)是否具有任何属性。 |
String | getNodeValue() | 此节点的值,取决于其类型;。 |
Node | getLastChild() | 此节点的最后一个节点。 |
3)NodeList : 此接口表示一个节点的集合,一般用于表示一组有顺序关系的节点。例如,一个节点的子节点,当文档改变时会直接影响到NodeList集合。
NodeList接口常用方法:
方法返回值 | 方法定义 | 方法含义 |
---|---|---|
int | getLength() | 列表中的节点数。 |
Node | item(int index) | 返回集合中的第 index 个项。 |
4)NamedNodeMap:此接口表示一组节点和其唯一名称的一一对应关系,主要用于属性节点的表示。
3.DOM解析的步骤
- 建立DocumentBuilderFactory:DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- 建立DocumentBuilder:DocumentBuilder builder = factory.newDocumentBuilder();
- Document doc = builder.parse(“要读取的文件路径”);
- 建立NodeList:NodeList nl = doc.getElementsByTagName(“读取节点”);
- 进行XML信息读取。
4.DOM解析XML
将要进行解析的XML文件:
<?xml version="1.0" encoding="GBK"?>
<addresslist>
<linkman>
<name>王三</name>
<email>123456789@qq.com</email>
</linkman>
<linkman>
<name>李四</name>
<email>4568975@qq.com</email>
</linkman>
</addresslist>
使用DOM去解析XML
package com.wzy.dom;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* 解析指定XML文件.
* @author wzy
*
*/
public class DOMDemo01 {
public static void main(String[] args) {
//(1)建立DocumentBuilderFactory,以用取得DocumentBuilder
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//(2)建立DocumentBuilderFactory取得DocumentBuilder
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
//(3)定义Document接口对象,通过DocumentBuilder类进行DOM树的转换操作
Document doc = null;
try {
doc = builder.parse("src/dom.xml");
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
NodeList nodeList = doc.getElementsByTagName("linkman");
for(int i = 0; i < nodeList.getLength(); i++) {//循环输出节点内容
Element e = (Element)nodeList.item(i);//取出每一元素
System.out.println("姓名:" + e.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
System.out.println("email:" + e.getElementsByTagName("email").item(0).getFirstChild().getNodeValue());
}
}
}
5.使用DOM去生成XML
package com.wzy.dom;
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.Document;
import org.w3c.dom.Element;
/**
* 将生成的XML文件输出到文件中
* @author wzy
*
*/
public class DOMDemo03 {
public static void main(String[] args) {
//(1)建立DocumentBuilderFactory,以用于取得DocumentBuilder
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//(2)通过DocumentBuilderFactory取得DocumentBuilder
DocumentBuilder builder= null;
try {
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
//(3)定义Document接口对象,通过DocumentBuilder类进行DOM树的转换工作。
Document doc = null;
doc = builder.newDocument();//创建一个新文档
//(4)建立各个操作节点
Element addresslist = doc.createElement("addresslist");
Element linkman = doc.createElement("linkman");
Element name = doc.createElement("name");
Element email = doc.createElement("email");
//(5)设置节点的文本内容,即为每一个节点添加文本节点。
name.appendChild(doc.createTextNode("王志远"));
email.appendChild(doc.createTextNode("842089160@qq.com"));
//(6)设置节点关系
linkman.appendChild(name);
linkman.appendChild(email);
addresslist.appendChild(linkman);
doc.appendChild(addresslist);
//(7)输出文档到文件中
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = null;
try {
t = tf.newTransformer();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
}
t.setOutputProperty(OutputKeys.ENCODING, "GBK");//设置编码
DOMSource source = new DOMSource(doc);//输出文档
StreamResult result = new StreamResult("src/dom2.xml");//指定输出位置
try {
t.transform(source, result);//输出
} catch (TransformerException e) {
e.printStackTrace();
}
}
}