基于DOM的XML解析
前言
想必学习过js的朋友们一定对DOM熟悉了把? js对html的操作就是基于DOM的,今天学习XML过程中,又遇见了它,DOM是W3C的规范,官方版,下面我们就一起来探讨一下把
DOM原理
DOM原理就在于从XML->对象树模型,然后对这棵树进行一系列的操作.
步骤:
- DocumentBuilderFactory获得工厂实例
- DocumentBuilder获得解析器
- parse通过解析器方法装载xml文档,获得Document树这样的实例
具体操作
package hello;
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 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.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
/**
* 使用DOM进行CURD操作
*/
public class XMLTools {
public Document getDocument(File xml) {
Document document = null;
// 1.获得工厂实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 2.获得解析器
try {
DocumentBuilder builder = factory.newDocumentBuilder();
// 3.获得Document对象
document = builder.parse(xml);
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
return document;
}
public static void writeFile(Document document, File file) {
// 获得转换工厂
TransformerFactory factory = TransformerFactory.newInstance();
try {
// 获得转换器
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// 将文档节点转换进文件里面
transformer.transform(new DOMSource(document), new StreamResult(file));
} catch (TransformerException e) {
e.printStackTrace();
}
}
// 读操作
public String getNodeContext(String node, Document document) {
NodeList list = document.getElementsByTagName(node);
Node target = list.item(0);
return target.getTextContent();
}
// 修改节点的值
public void update(Document document, String node, String text, File file) {
Node old = document.getElementsByTagName(node).item(0);
old.setTextContent(text);
writeFile(document, file);
}
// 尾部增加节点
public void add(Document document, String node, String text, String parent, File file) {
Node newNode = document.createElement(node);
newNode.setTextContent(text);
Node postion = document.getElementsByTagName(parent).item(0);
postion.appendChild(newNode);
writeFile(document, file);
}
// 指定位置增加节点
public void insertBefore(Document document, String node, String postion, File file) {
Node newNode = document.createElement(node);
Node target = document.getElementsByTagName(postion).item(0);
Node parent = target.getParentNode();
parent.insertBefore(newNode, target);
writeFile(document, file);
}
public void insertAfter(Document document, String node, String postion, File file) {
Node newNode = document.createElement(node);
Node target = document.getElementsByTagName(postion).item(0);
Node parent = target.getParentNode();
Node next = target.getNextSibling();
parent.insertBefore(newNode, next);
writeFile(document, file);
}
// 删除制定节点
public void deleteNode(Document document, String node, File file) {
Node old = document.getElementsByTagName(node).item(0);
old.getParentNode().removeChild(old);
writeFile(document, file);
}
// 操作xml属性
public void OperateAttr(Document document, String node, File file) {
// 在强制转换节点时先进行判断
Element element = null;
Node old = document.getElementsByTagName(node).item(0);
if (old.getNodeType() == Node.ELEMENT_NODE) {
element = (Element) old;
}
if (element != null) {
element.setAttribute("name", "123");
element.setAttribute("key", "123");
element.removeAttribute("key");
}
writeFile(document, file);
}
// 遍历xml
public void list(Node node) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(node.getNodeName());
}
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node child = list.item(i);
list(child);
}
}
}
美化小技巧
- 我们对xml操作之后它的代码是乱的,这个时候我们可以通过这个方法来进行缩进处理:
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- 但是这个时候又有新的问题,它会在原来已经缩进的基础上,再次缩进,就会带来不必要的空行,笔者找到的解决方法是使用IDEA编辑器中的功能,具体如下
顺序是:File–>Setting–>Editor–>Code Style –>XML
之后ctrl+alt+l 就可以实现美化了~
DOM的优缺点
优点:CURD快,效率高
缺点:它是一下子把整个xml加入到内存里面,对于内存的要求会比较大,java虚拟机内存默认64M,可以通过-Xmx来进行修改
总结
相对的操作还是挺简单的,实现了CURD,不足的地方就在于代码复用差了点,参数多了点,最后还得根据实际工程来进行相关的修改.这次主要是体验了一把XML的魅力,后面还有一个小系统,可以来加深下印象