• Dom4j节点处理器的实现


     
     
    Dom4j为XML文档解析提供了强大的API支持,在实际开发中,为了处理方便,常常以节点元素(Element)为单位进行处理,并且结合数据库和Java技术,为节点生成ID属性。这样,就很有必要在Dom4j的基础上,重新封装一些适用需要的方法,以提高开发效率。下面是我利用业余时间做的一个Dom4j节点处理器工具类的实现。希望能节省开发人员宝贵时间。
     

    说明:为了写起来方便,可以单独运行,我没有写单独的测试类,实际用的时候,删除掉测试main()和test()方法即可。

     
    注释很详细,不用废话了。下面是处理器的实现:
     
    测试用的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"?> " + 
                    "<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>"
            String nodeXml1 = "            <add > " + 
                    "                <BS></BS> " + 
                    "                <note>西安市太白路1</note> " + 
                    "            </add>"

            String nodeXml2 = "            <add> " + 
                    "                <note>西安市太白路2</note> " + 
                    "            </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。放到以方便查看。 

    衷心祝福广大支持和浏览熔岩博客的朋友们:周末愉快!!! 
  • 相关阅读:
    Spring AOP @Before @Around @After 等 advice 的执行顺序
    web服务启动spring自动执行ApplicationListener的用法
    Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法
    ApplicationContextAware使用理解
    查询oracle比较慢的session和sql
    使用ANTS Performance Profiler&ANTS Memory Profiler工具分析IIS进程内存和CPU占用过高问题
    C#控制台程序中处理2个关闭事件的代码实例
    mysql优化----第一篇:综述
    HMM 隐马尔科夫模型
    EM 期望最大化算法
  • 原文地址:https://www.cnblogs.com/honglihome/p/3440453.html
Copyright © 2020-2023  润新知