写文章的基本章程,我们废话不说,先说废话。
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小强
未曾清贫难成人,不经打击老天真。
自古英雄出炼狱,从来富贵入凡尘。
发表评论: