写文章的基本章程,我们废话不说,先说废话。
Dom4j 是一个用于处理 XML 的开源框架,该框架与 XPath 集成在一起,并完全支持 DOM、SAX、JAXP 和 Java 平台(例如 Java 2 Collections)。
dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面还可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包, Hibernate也用它来读写配置文件。

官网地址:
一般我们需要的就是对XML的读取、赋值、复制、删除,CRUD嘛。
如果按照网上的手法,解析将是一件特别痛苦的事情,这里提供一些工具类,可以方便的实现CRUD操作。
我们需要操作的XML内容如下,非常不标准因为仅为测试
<?xml version="1.0" encoding="UTF-8" ?> <root> <a> <b> <c> <d /> </c> <c> <d /> <d> <e /> <e> <f /> <f name="" ></f> <f /> </e> <e /> </d> <d /> </c> <c> <d /> </c> </b> </a> </root>
可以看到各种嵌套,如果要自己解析的,那会非常痛苦。
工具类代码:
package com.example.demo;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
public class XMLUtil {
/**
* 写数据到指定节点
* @param xml xml文本
* @param nodePath 节点路径
* @param value 节点值
*/
public static String write(String xml, String nodePath, String value) throws DocumentException {
if (!nodePath.contains("/@")){
throw new IllegalArgumentException(nodePath+",节点错误,没有/@");
}
Document document1 = DocumentHelper.parseText(xml);
Element rootElement = document1.getRootElement();
String[] path = nodePath.split("/@");
String attribute = path[1];
nodePath = path[0];
String[] split = nodePath.split("/");
for (String s : split) {
if (isEmpty(s)) continue;
try {
if(s.contains("[") && s.contains("]")){
//多节点下标
int index = Integer.parseInt(s.substring(s.indexOf("[") + 1, s.indexOf("]")));
//节点名称
s = s.substring(0, s.indexOf("["));
rootElement = rootElement.elements(s).get(index);
}else {
rootElement = rootElement.element(s);
}
} catch (Exception e) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
}
if (null == rootElement) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
if (rootElement.attribute(attribute) == null) {
throw new IllegalArgumentException(nodePath+",节点"+attribute+"属性不存在");
}
rootElement.attribute(attribute).setValue(isNull(value));
return document1.asXML();
}
/**
* 写数据到指定节点
* @param xml xml文本
* @param nodePath 节点路径
* @param value 节点值
*/
public static String writeValue(String xml, String nodePath, Object value) throws DocumentException {
if (nodePath.contains("/@")){
throw new IllegalArgumentException(nodePath+",节点错误,不能有/@");
}
Document document1 = DocumentHelper.parseText(xml);
Element rootElement = document1.getRootElement();
String[] split = nodePath.split("/");
for (String s : split) {
if (isEmpty(s)) continue;
try {
if(s.contains("[") && s.contains("]")){
//多节点下标
int index = Integer.parseInt(s.substring(s.indexOf("[") + 1, s.indexOf("]")));
//节点名称
s = s.substring(0, s.indexOf("["));
rootElement = rootElement.elements(s).get(index);
}else {
rootElement = rootElement.element(s);
}
} catch (Exception e) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
}
if (null == rootElement) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
rootElement.setText(isNull(value));
return document1.asXML();
}
/**
* 获取指定节点
* @param xml xml文本
* @param nodePath 节点路径
*/
public static Element getElement(String xml, String nodePath){
try {
Document document1 = DocumentHelper.parseText(xml);
Element rootElement = document1.getRootElement();
String[] split = nodePath.split("/");
for (String s : split) {
if (isEmpty(s)) continue;
try {
if(s.contains("[") && s.contains("]")){
//多节点下标
int index = Integer.parseInt(s.substring(s.indexOf("[") + 1, s.indexOf("]")));
//节点名称
s = s.substring(0, s.indexOf("["));
rootElement = rootElement.elements(s).get(index);
}else {
rootElement = rootElement.element(s);
}
} catch (Exception e) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
}
if (null == rootElement) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
return rootElement;
} catch (DocumentException e) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
}
/**
* 添加新节点到指定节点下
* @param xml xml文本
* @param nodePath 节点路径
* @param element 节点值
*/
public static String addElement(String xml, String nodePath, Element element) throws DocumentException {
Document document1 = DocumentHelper.parseText(xml);
Element rootElement = document1.getRootElement();
String[] split = nodePath.split("/");
for (String s : split) {
if (nodePath.equals("/")) break;
if (isEmpty(s)) continue;
try {
if(s.contains("[") && s.contains("]")){
//多节点下标
int index = Integer.parseInt(s.substring(s.indexOf("[") + 1, s.indexOf("]")));
//节点名称
s = s.substring(0, s.indexOf("["));
rootElement = rootElement.elements(s).get(index);
}else {
rootElement = rootElement.element(s);
}
} catch (Exception e) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
}
if (null == rootElement) {
throw new IllegalArgumentException(nodePath+",节点不存在");
}
// 不存在节点,添加新的节点
rootElement.add(element);
return document1.asXML();
}
/**
* 删除指定节点
* @param xml xml文本
* @param nodePath 节点路径
*/
public static String removeElement(String xml, String nodePath) throws DocumentException {
Document document1 = DocumentHelper.parseText(xml);
Element rootElement = document1.getRootElement();
String[] split = nodePath.split("/");
Element element = rootElement;
for (String s : split) {
if (isEmpty(s)) continue;
try {
if(s.contains("[") && s.contains("]")){
//多节点下标
int index = Integer.parseInt(s.substring(s.indexOf("[") + 1, s.indexOf("]")));
//节点名称
s = s.substring(0, s.indexOf("["));
element = element.elements(s).get(index);
}else {
element = element.element(s);
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
if (element != rootElement) {
// 删除节点
element.getParent().remove(element);
}
return document1.asXML();
}
/**
* 删除指定的节点属性
* @param xml 原xml文本
* @return 删除后的xml文本
*/
// public static String deleteDescSn(String xml) throws DocumentException {
// if (xml == null || xml.isEmpty()) return xml;
// Document document1 = DocumentHelper.parseText(xml);
// Element rootElement = document1.getRootElement();
// List<Element> elements = rootElement.elements();
// deleteS(elements);
// return document1.asXML();
// }
/**
* 删除不必要的数据
* @param elements xml数据源
*/
// private static void deleteS(List<Element> elements){
// for (Element element : elements) {
// Attribute desc = element.attribute("desc");
// if (desc != null) {
// element.remove(desc);
// }
// Attribute sn = element.attribute("sn");
// if (sn != null) {
// element.remove(sn);
// }
// List<Element> elements2 = element.elements();
// if (elements2.size() > 0) {
// deleteS(elements2);
// }
// }
// }
public static boolean isEmpty(String str) {
if (str != null) {
int len = str.length();
for (int x = 0; x < len; ++x) {
if (str.charAt(x) > ' ') {
return false;
}
}
}
return true;
}
public static String isNull(Object value) {
if (null == value) {
return "";
}
return value.toString().trim();
}
}使用代码
package com.example.demo;
import java.io.File;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;
public class XmlEdit {
public static void main(String[] args) throws Exception {
SAXReader reader = new SAXReader();
File file = new File("C:\\test.xml");
Document document = reader.read(file);
String dataString = document.asXML();
dataString = XMLUtil.write(dataString,"/a/b/c[1]/d[1]/e[1]/f[1]/@name", "java小强");
dataString = XMLUtil.writeValue(dataString,"/a/b/c[1]/d[1]/e[1]/f[1]/", "www.javacui.com");
// 获得上面赋值的那个节点
Element element = XMLUtil.getElement(dataString, "/a/b/c[1]/d[1]/e[1]/f[1]/");
// 获得该节点内容
System.out.println(element.attributeValue("name") + " ---> " + element.getText());
// 复制一个节点,上面已经赋值,内容将全部拷贝
Element copy = element.createCopy(QName.get("f", element.getParent().getNamespace ()));
dataString = XMLUtil.addElement(dataString,"/a/b/c[1]/d[1]/e[1]/",copy);
// 删除一个上面复制的那个节点
dataString = XMLUtil.removeElement(dataString, "/a/b/c[1]/d[1]/e[1]/f[1]/");
System.out.println(dataString);
}
}输出内容
java小强 ---> www.javacui.com <?xml version="1.0" encoding="UTF-8"?> <root> <a> <b> <c> <d/> </c> <c> <d/> <d> <e/> <e> <f/> <f/> <f name="java小强">www.javacui.com</f></e> <e/> </d> <d/> </c> <c> <d/> </c> </b> </a> </root>
赋值时,注意write和writeValue,读取复制删除,完成了CRUD操作。
END
Java小强
未曾清贫难成人,不经打击老天真。
自古英雄出炼狱,从来富贵入凡尘。
发表评论: