优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
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.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
*
* @author hongliang.dinghl DOM生成与解析XML文档
*/
public class DomDemo {
private Document document;
private String fileName;
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) {
//创建一个新的文档对象
init();
//根节点
Element root = this.document.createElement("employees");
//将根节点加载到文档对象中
this.document.appendChild(root);
//创建子元素
Element employee = this.document.createElement("employee");
Element name = this.document.createElement("name");
//添加文本节点
name.appendChild(this.document.createTextNode("qiankunshe"));
employee.appendChild(name);
Element age = this.document.createElement("age");
age.appendChild(this.document.createTextNode("25"));
employee.appendChild(age);
//添加层级关系
root.appendChild(employee);
TransformerFactory tf = TransformerFactory.newInstance();
try {
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
//添加xml 头信息
transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//输出xml流信息包装类
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
StreamResult result = new StreamResult(pw);
//将xml写到文件中
transformer.transform(source, result);
System.out.println("生成XML文件成功!");
} catch (TransformerConfigurationException e) {
System.out.println(e.getMessage());
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (TransformerException e) {
System.out.println(e.getMessage());
}
}
public void parserXml(String fileName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
//将xml文件解析
Document document = db.parse(fileName);
//获得所有节点,递归遍历节点
NodeList employees = document.getChildNodes();
for (int i = 0; i < employees.getLength(); i++) {
//取得一个节点
Node employee = employees.item(i);
NodeList employeeInfo = employee.getChildNodes();
for (int j = 0; j < employeeInfo.getLength(); j++) {
Node node = employeeInfo.item(j);
NodeList employeeMeta = node.getChildNodes();
for (int k = 0; k < employeeMeta.getLength(); k++) {
System.out.println(employeeMeta.item(k).getNodeName()
+ ":" + employeeMeta.item(k).getTextContent());
}
}
}
System.out.println("解析完毕");
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
} catch (SAXException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
* 创建xml
1、创建文档对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
this.document = builder.newDocument();
上面三句话是创建一个文档对象,第一步是获得一个文档解析工厂对象,第二步是通过工厂方法创建一个新的解析对象,第三步是创建一个新的文档对象
2、创建元素节点节点
Element root = this.document.createElement("employees");
3、创建属性节点
root.setAttribute("name", "liu");
4、创建文本子节点
root.appendChild(this.document.createTextNode("qiankunshe"));
5、文本加入到文档对象中
this.document.appendChild(root);
到这里就要描述下xml文档的结构了
1、xml为树形结构(如果学习过html的同学应该是知道的,html为特殊的xml),由根节点——》枝节点——》叶节点
以下图职员信息xml为例:
其中employees为根节点,employe、name、age都是枝节点(这些节点都是元素节点)
而liu、25为文本节点
通过上图说明了,我们在创建xml时,employees包含n个employe元素,employe元素有包含了一个name和一个age元素
理论上这个语句就表名我们要的方法了document.appendChild(root);
只不过document变成了employees或employe、name、age了,但要记得一点就是节点只能添加到元素节点下面
xml解析
public void parserXml(String fileName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
//将xml文件解析
Document document = db.parse(fileName);
//获得所有节点,递归遍历节点
NodeList employees = document.getChildNodes();
for (int i = 0; i < employees.getLength(); i++) {
//取得一个节点
Node employee = employees.item(i);
NodeList employeeInfo = employee.getChildNodes();
for (int j = 0; j < employeeInfo.getLength(); j++) {
Node node = employeeInfo.item(j);
NodeList employeeMeta = node.getChildNodes();
for (int k = 0; k < employeeMeta.getLength(); k++) {
System.out.println(employeeMeta.item(k).getNodeName()
+ ":" + employeeMeta.item(k).getTextContent());
}
}
}
System.out.println("解析完毕");
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
} catch (SAXException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
1.创建解析对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
2.解析文件
Document document = db.parse(fileName);
3.获得文档第一层节点
NodeList employees = document.getChildNodes();
4.一层一层的解析完毕
NodeList employees = employees.item(i).getChildNodes();
使用原生api进行解析时,可以先使用
document.getElementById("");
document.getElementsByTagName("");
直接获得自己要解析的对象
使用原生的api的问题
1.对xml格式有强依赖,有换行和无换行的xml,解析出来的东西是不同的(会多几个文本节点)
2.为一次性加载,对于解析大的xml来说,可能会出现内存溢出的情况
解决方式
1.加入类型判断,如:node.getNodeType() == Node.ELEMENT_NODE; 判断节点是不是元素节点
2.对于太大的xml可以适当的截取,来解析