Dom4j节点处理器的实现
Dom4j节点处理器的实现
Dom4j为XML文档解析提供了强大的API支持,在实际开发中,为了处理方便,常常以节点元素(Element)为单位进行处理,并且结合
数据库和Java技术,为节点生成ID属性。这样,就很有必要在Dom4j的基础上,重新封装一些适用需要的方法,以提高开发效率。下面是我利用业余时间
做的一个Dom4j节点处理器工具类的实现。希望能节省开发人员宝贵时间。
注释很详细,不用废话了。下面是处理器的实现:
测试用的xml:
输出三个测试对象
----------srcXml------------ <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10001"> <BS>10001</BS> <note>郑州市经三路</note> </add> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> <add ID=""> <BS>10002</BS> <note>空ID节点啊</note> </add> <add> <BS>10002</BS> <note>空ID节点啊</note> </add> </adds> </person> <other> <name ID="HEHE">ASDF</name> <name>空ID节点啊</name> <name>空ID节点啊</name> </other> </doc> ----------nodeXml1------------ <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10001"> <BS>10001</BS> <note>郑州市经三路</note> </add> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> <add ID=""> <BS>10002</BS> <note>空ID节点啊</note> </add> <add> <BS>10002</BS> <note>空ID节点啊</note> </add> </adds> </person> <other> <name ID="HEHE">ASDF</name> <name>空ID节点啊</name> <name>空ID节点啊</name> </other> </doc> ----------nodeXml2------------ <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10001"> <BS>10001</BS> <note>郑州市经三路</note> </add> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> <add ID=""> <BS>10002</BS> <note>空ID节点啊</note> </add> <add> <BS>10002</BS> <note>空ID节点啊</note> </add> </adds> </person> <other> <name ID="HEHE">ASDF</name> <name>空ID节点啊</name> <name>空ID节点啊</name> </other> </doc> 处理器的实现类:
package com.topsoft.icib.common.utils;
import org.dom4j.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.lang.StringUtils; import java.util.Random; import java.util.Iterator; import java.util.ArrayList; /** * Created by IntelliJ IDEA.<br> * <b>User</b>: leizhimin<br> * <b>Date</b>: 2008-3-27 18:42:39<br> * <b>Note</b>: XML节点处理器,包含XML元素的CRUD方法。 */ public class XmlNodeHandler { private static Log log = LogFactory.getLog(XmlNodeHandler.class); /** * 在xml的指定位置插入一个元素 * * @param srcXml 原xml * @param nodeXml 元素xml * @param xpath 要插入元素父节点的位置 * @return 原xml插入节点后的完整xml文档 */ public static String addElement(String srcXml, String nodeXml, String xpath) { String resultXml = null; try { Document docSrc = DocumentHelper.parseText(srcXml); Document docNode = DocumentHelper.parseText(nodeXml); Element parentElement = (Element) docSrc.getRootElement().selectSingleNode(xpath); parentElement.add(docNode.getRootElement()); resultXml = docSrc.asXML(); } catch (DocumentException e) { log.error("在文档" + xpath + "位置添加新节点发生异常,请检查!"); System.out.println(e.getMessage()); e.printStackTrace(); } return resultXml; } /** * 删除xml文档中指定ID的元素 * * @param srcXml 原xml * @param xmlNodeId 元素ID属性值 * @return 删除元素后的xml文档 */ public static String removeElementById(String srcXml, String xmlNodeId) { String resultXml = null; try { Document docSrc = DocumentHelper.parseText(srcXml); Element removeElement = docSrc.getRootElement().elementByID(xmlNodeId); removeElement.detach(); //直接删除自己 // removeElement.getParent().remove(removeElement); //从父节点删除子节点 resultXml = docSrc.asXML(); } catch (DocumentException e) { log.error("删除文档中ID为" + xmlNodeId + "的节点发生异常,请检查!"); System.out.println(e.getMessage()); e.printStackTrace(); } return resultXml; } /** * 删除xml文档中以xpath为直接父节点的ID属性为空的子节点,ID属性为空包括值为空、空串、或者ID属性不存在。 * * @param srcXml 原xml文档 * @param xpath 要删除空节点的所在父节点的xpath * @return 删除空节点后的xml文档 */ public static String removeNullIdElement(String srcXml, String xpath) { String resultXml = null; try { Document srcDoc = DocumentHelper.parseText(srcXml); removeNullIdElement(srcDoc, xpath); resultXml = srcDoc.asXML(); } catch (DocumentException e) { log.error("在" + xpath + "下删除空节点发生异常,请检查xpath是否正确!"); System.out.println(e.getMessage()); e.printStackTrace(); } return resultXml; } /** * 删除xml文档中以xpath为直接父节点的ID属性为空的子节点,ID属性为空包括值为空、空串、或者ID属性不存在。 * * @param srcDoc 原xml的Document对象 * @param xpath 要删除空节点的所在父节点的xpath * @return 删除空节点后的xml文档 */ public static Document removeNullIdElement(Document srcDoc, String xpath) { Node parentNode = srcDoc.getRootElement().selectSingleNode(xpath); if (!(parentNode instanceof Element)) { log.error("所传入的xpath不是Elementpath,删除空节点失败!"); } else { int i = 0; for (Iterator<Element> it = ((Element) parentNode).elementIterator(); it.hasNext();) { Element element = it.next(); if (element.attribute("ID") == null) { element.detach(); i++; } else { if (StringUtils.isBlank(element.attribute("ID").getValue())) { element.detach(); i++; }
} } log.info("在" + xpath + "下成功删除" + i + "了个空节点!"); } return srcDoc; } /** * 删除xml文档中指定xpath路径下所有直接子节点为空的节点 * * @param srcXml 原xml文档 * @param xpathList xpaht列表 * @return 删除空节点后的xml文档 */ public static String removeAllNullIdElement(String srcXml, ArrayList<String> xpathList) { String resultXml = null; try { Document srcDoc = DocumentHelper.parseText(srcXml); for (Iterator<String> it = xpathList.iterator(); it.hasNext();) { String xpath = it.next(); removeNullIdElement(srcDoc, xpath); } resultXml = srcDoc.asXML(); } catch (DocumentException e) { System.out.println(e.getMessage()); e.printStackTrace(); } return resultXml; } /** * 更新xml文档中指定ID的元素,ID保持不变 * * @param srcXml 原xml * @param newNodeXml 新xml节点 * @param xmlNodeId 更新元素ID属性值 * @return 更新元素后的xml文档 */ public static String updateElementById(String srcXml, String newNodeXml, String xmlNodeId) { String resultXml = null; try { Document docSrc = DocumentHelper.parseText(srcXml); Document newDocNode = DocumentHelper.parseText(newNodeXml); //获取要更新的目标节点 Element updatedNode = docSrc.elementByID(xmlNodeId); //获取更新目标节点的父节点 Element parentUpNode = updatedNode.getParent(); //删除掉要更新的节点 parentUpNode.remove(updatedNode); //获取新节点的根节点(作为写入节点) Element newRoot = newDocNode.getRootElement(); //处理新节点的ID属性值和BS子元素的值 if (newRoot.attribute("ID") == null) { newRoot.addAttribute("ID", xmlNodeId); } else { newRoot.attribute("ID").setValue(xmlNodeId); } //在原文档中更新位置写入新节点 parentUpNode.add(newRoot); resultXml = docSrc.asXML(); } catch (DocumentException e) { log.error("更新xml文档中ID为" + xmlNodeId + "节点发生异常,请检查!"); System.out.println(e.getMessage()); e.printStackTrace(); } return resultXml; } /** * 更新xml文档中指定ID的元素,并检查ID和BS,加以设置 * * @param srcXml 原xml * @param newNodeXml 新xml节点 * @param xmlNodeId 更新元素ID属性值 * @return 更新元素后的xml文档 */ public static String updateElementByIdAddIdBs(String srcXml, String newNodeXml, String xmlNodeId) { String resultXml = null; try { Document docSrc = DocumentHelper.parseText(srcXml); Document newDocNode = DocumentHelper.parseText(newNodeXml); //获取要更新的目标节点 Element updatedNode = docSrc.elementByID(xmlNodeId); //获取更新目标节点的父节点 Element parentUpNode = updatedNode.getParent(); //删除掉要更新的节点 parentUpNode.remove(updatedNode); //获取新节点的根节点(作为写入节点) Element newRoot = newDocNode.getRootElement(); //处理新节点的ID属性值和BS子元素的值 if (newRoot.attribute("ID") == null) { newRoot.addAttribute("ID", xmlNodeId); } else { newRoot.attribute("ID").setValue(xmlNodeId); } if (newRoot.element("BS") == null) { newRoot.addElement("BS", xmlNodeId); } else { newRoot.element("BS").setText(xmlNodeId); } //在原文档中更新位置写入新节点 parentUpNode.add(newRoot); resultXml = docSrc.asXML(); } catch (DocumentException e) { log.error("更新xml文档中ID为" + xmlNodeId + "节点发生异常,请检查!"); System.out.println(e.getMessage()); e.printStackTrace(); } return resultXml; } /** * 为xml元素设置ID属性 * * @param xmlElement 原xml元素 * @return 设置id后的xml串 */ public static String addIdAttribute(String xmlElement) { String resultXml = null; try { Document srcDoc = DocumentHelper.parseText(xmlElement); Element root = srcDoc.getRootElement(); // Long nextValue = SequenceUtils.getSequeceNextValue(); Long nextValue = new Random().nextLong(); root.addAttribute("ID", nextValue.toString()); resultXml = root.asXML(); } catch (DocumentException e) { log.error("给xml元素设置ID属性发生异常,请检查!"); System.out.println(e.getMessage()); e.printStackTrace(); } return resultXml; } /** * 为xml元素设置ID属性,并将此属性写入一个指定子节点文本值域 * * @param xmlElement 原xml元素 * @param nodeName (直接)子节点的名称,或相对当前节点的xpath路径 * @return 设置id和子节点后的xml串 */ public static String addIdAndWriteNode(String xmlElement, String nodeName) { String resultXml = null; try { Document srcDoc = DocumentHelper.parseText(xmlElement); Element root = srcDoc.getRootElement(); // Long nextValue = SequenceUtils.getSequeceNextValue(); Long nextValue = new Random().nextLong(); root.addAttribute("ID", nextValue.toString()); Node bsElement = root.selectSingleNode(nodeName); if (bsElement instanceof Element && bsElement != null) { bsElement.setText(nextValue.toString()); } else { root.addElement(nodeName).setText(nextValue.toString()); } resultXml = root.asXML(); } catch (DocumentException e) { log.error("给xml元素设置ID属性和直接" + nodeName + "子元素值时发生异常,请检查!"); System.out.println(e.getMessage()); e.printStackTrace(); } return resultXml; } public static void main(String args[]) { test(); } public static void test() { System.out.println("----------test()----------"); String srcXml = "<?xml version=\"1.0\" encoding=\"GBK\"?>\n" + "<doc>\n" + " <person>\n" + " <name>某人</name>\n" + " <adds>\n" + " <add ID=\"10001\">\n" + " <BS>10001</BS>\n" + " <note>郑州市经三路</note>\n" + " </add>\n" + " <add ID=\"10002\">\n" + " <BS>10002</BS>\n" + " <note>西安市太白路</note>\n" + " </add>\n" + " <add ID=\"\">\n" + " <BS>10002</BS>\n" + " <note>空ID节点啊</note>\n" + " </add>\n" + " <add>\n" + " <BS>10002</BS>\n" + " <note>空ID节点啊</note>\n" + " </add>\n" + " </adds>\n" + " </person>\n" + " <other>\n" + " <name ID=\"HEHE\">ASDF</name>\n" + " <name>空ID节点啊</name>\n" + " <name>空ID节点啊</name>\n" + " </other>\n" + "</doc>"; String nodeXml1 = " <add >\n" + " <BS></BS>\n" + " <note>西安市太白路1</note>\n" + " </add>"; String nodeXml2 = " <add>\n" + " <note>西安市太白路2</note>\n" + " </add>"; // System.out.println("输出三个测试对象"); // System.out.println("----------srcXml------------"); // System.out.println(srcXml); // System.out.println("----------nodeXml1------------"); // System.out.println(srcXml); // System.out.println("----------nodeXml2------------"); // System.out.println(srcXml); System.out.println("----------addElement()测试----------"); String addrs = addElement(srcXml, nodeXml1, "/doc/person/adds"); System.out.println(addrs); System.out.println("----------addIdAttribute()测试----------"); String addIdrs = addIdAttribute(nodeXml1); System.out.println(addIdrs); System.out.println("----------addIdAndWriteNode()测试----------"); String addIdNoders = addIdAndWriteNode(nodeXml1, "BS"); System.out.println(addIdNoders); System.out.println("----------removeElementById()测试----------"); String removeIdrs = removeElementById(srcXml, "10001"); System.out.println(removeIdrs); System.out.println("----------updateElementByIdAddIdBs()测试----------"); String upbyidrs = updateElementByIdAddIdBs(srcXml, nodeXml2, "10001"); System.out.println(upbyidrs); System.out.println("----------updateElementById()测试----------"); String upbyidrs1 = updateElementById(srcXml, nodeXml2, "10001"); System.out.println(upbyidrs1); System.out.println("----------removeNullIdElement()测试----------"); String rvnullrs = removeNullIdElement(srcXml, "/doc/person/adds"); System.out.println(rvnullrs); System.out.println("----------removeAllNullIdElement()测试----------"); ArrayList<String> xpathList = new ArrayList<String>(); xpathList.add("/doc/person/adds"); xpathList.add("/doc/other"); String rvallnullrs = removeAllNullIdElement(srcXml, xpathList); System.out.println(rvallnullrs); System.out.println("----------Dom4j生成一个xml测试----------"); Document doc = DocumentHelper.createDocument(); doc.addElement("root") .addElement("person").setText("haha:)"); System.out.println(doc.asXML()); } } 运行结果:
----------test()----------
----------addElement()测试---------- <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10001"> <BS>10001</BS> <note>郑州市经三路</note> </add> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> <add ID=""> <BS>10002</BS> <note>空ID节点啊</note> </add> <add> <BS>10002</BS> <note>空ID节点啊</note> </add> <add> <BS/> <note>西安市太白路1</note> </add></adds> </person> <other> <name ID="HEHE">ASDF</name> <name>空ID节点啊</name> <name>空ID节点啊</name> </other> </doc> ----------addIdAttribute()测试---------- <add ID="7549173897283584063"> <BS/> <note>西安市太白路1</note> </add> ----------addIdAndWriteNode()测试---------- <add ID="8974292836389323633"> <BS>8974292836389323633</BS> <note>西安市太白路1</note> </add> ----------removeElementById()测试---------- <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> <add ID=""> <BS>10002</BS> <note>空ID节点啊</note> </add> <add> <BS>10002</BS> <note>空ID节点啊</note> </add> </adds> </person> <other> <name ID="HEHE">ASDF</name> <name>空ID节点啊</name> <name>空ID节点啊</name> </other> </doc> ----------updateElementByIdAddIdBs()测试---------- <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> <add ID=""> <BS>10002</BS> <note>空ID节点啊</note> </add> <add> <BS>10002</BS> <note>空ID节点啊</note> </add> <add ID="10001"> <note>西安市太白路2</note> <BS xmlns="10001"/></add></adds> </person> <other> <name ID="HEHE">ASDF</name> <name>空ID节点啊</name> <name>空ID节点啊</name> </other> </doc> ----------updateElementById()测试---------- <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> <add ID=""> <BS>10002</BS> <note>空ID节点啊</note> </add> <add> <BS>10002</BS> <note>空ID节点啊</note> </add> <add ID="10001"> <note>西安市太白路2</note> </add></adds> </person> <other> <name ID="HEHE">ASDF</name> <name>空ID节点啊</name> <name>空ID节点啊</name> </other> </doc> ----------removeNullIdElement()测试---------- 16:17:32,689 INFO XmlNodeHandler:113 - 在/doc/person/adds下成功删除4了个空节点! <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10001"> <BS>10001</BS> <note>郑州市经三路</note> </add> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> </adds> </person> <other> <name ID="HEHE">ASDF</name> <name>空ID节点啊</name> <name>空ID节点啊</name> </other> </doc> ----------removeAllNullIdElement()测试---------- 16:17:32,705 INFO XmlNodeHandler:113 - 在/doc/person/adds下成功删除4了个空节点! 16:17:32,705 INFO XmlNodeHandler:113 - 在/doc/other下成功删除3了个空节点! <?xml version="1.0" encoding="GBK"?> <doc> <person> <name>某人</name> <adds> <add ID="10001"> <BS>10001</BS> <note>郑州市经三路</note> </add> <add ID="10002"> <BS>10002</BS> <note>西安市太白路</note> </add> </adds> </person> <other> <name ID="HEHE">ASDF</name> </other> </doc> ----------Dom4j生成一个xml测试---------- <?xml version="1.0" encoding="UTF-8"?> <root><person>haha:)</person></root> Process finished with exit code 0 程序中尽量避免用Dom4j之外的第三方类库,但是还用到了,可以修改一下:
1、用到Log4j的地方,可以修改log对象的实现为Java中的Logger工具: private static Logger log = Logger.getLogger(XmlNodeHandler.class.getName()); 2、用到apache的beanutils工具包中的StringUtils.isBlank()方法时候,可以改用JDK API String中的equel()方法做比较进行替换。具体操作很简单,我就不写了。 3、用到Sequence生成的Id的地方,我都改为java.util.Random类来实现,目的还是为了把眼光放到Dom的处理上。如果有博友对这个SequenceUtils工具类有兴趣,我可以把代码贴出去。 本处理器工具类涵盖Dom4j最常用部分80%以上的API。放到以方便查看。 衷心祝福广大支持和浏览熔岩博客的朋友们:周末愉快!!! |
|
来自: 知识储备库_wu... > 《我的图书馆》