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.
 
* User: leizhimin
 
* Date: 2008-3-27 18:42:39
 
* Note: 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 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 xpathList) { 
        String resultXml =  null
         try { 
            Document srcDoc = DocumentHelper.parseText(srcXml); 
             for (Iterator 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 =  "\n" + 
                 "\n" + 
                 "    \n" + 
                 "        某人\n" + 
                 "        \n" + 
                 "            \n" + 
                 "                10001\n" + 
                 "                郑州市经三路\n" + 
                 "            \n" + 
                 "            \n" + 
                 "                10002\n" + 
                 "                西安市太白路\n" + 
                 "            \n" + 
                 "            \n" + 
                 "                10002\n" + 
                 "                空ID节点啊\n" + 
                 "            \n" + 
                 "            \n" + 
                 "                10002\n" + 
                 "                空ID节点啊\n" + 
                 "            \n" + 
                 "        \n" + 
                 "    \n" + 
                 "    \n" + 
                 "        ASDF\n" + 
                 "        空ID节点啊\n" + 
                 "        空ID节点啊\n" + 
                 "    \n" + 
                 ""
        String nodeXml1 =  "            \n" + 
                 "                \n" + 
                 "                西安市太白路1\n" + 
                 "            "

        String nodeXml2 =  "            \n" + 
                 "                西安市太白路2\n" + 
                 "            "

//        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 xpathList =  new ArrayList(); 
        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()测试---------- 
 
 
     
        某人 
         
             
                10001 
                郑州市经三路 
            
 
             
                10002 
                西安市太白路 
            
 
             
                10002 
                空ID节点啊 
            
 
             
                10002 
                空ID节点啊 
            
 
         
                 
                西安市太白路1 
            
 
    
 
     
        ASDF 
        空ID节点啊 
        空ID节点啊 
    
 
 
----------addIdAttribute()测试---------- 
 
                 
                西安市太白路1 
            
 
----------addIdAndWriteNode()测试---------- 
 
                8974292836389323633 
                西安市太白路1 
            
 
----------removeElementById()测试---------- 
 
 
     
        某人 
         
             
             
                10002 
                西安市太白路 
            
 
             
                10002 
                空ID节点啊 
            
 
             
                10002 
                空ID节点啊 
            
 
        
 
    
 
     
        ASDF 
        空ID节点啊 
        空ID节点啊 
    
 
 
----------updateElementByIdAddIdBs()测试---------- 
 
 
     
        某人 
         
             
             
                10002 
                西安市太白路 
            
 
             
                10002 
                空ID节点啊 
            
 
             
                10002 
                空ID节点啊 
            
 
         
                西安市太白路2 
            
 
    
 
     
        ASDF 
        空ID节点啊 
        空ID节点啊 
    
 
 
----------updateElementById()测试---------- 
 
 
     
        某人 
         
             
             
                10002 
                西安市太白路 
            
 
             
                10002 
                空ID节点啊 
            
 
             
                10002 
                空ID节点啊 
            
 
         
                西安市太白路2 
            
 
    
 
     
        ASDF 
        空ID节点啊 
        空ID节点啊 
    
 
 
----------removeNullIdElement()测试---------- 
16:17:32,689  INFO XmlNodeHandler:113 - 在/doc/person/adds下成功删除4了个空节点! 
 
 
     
        某人 
         
             
                10001 
                郑州市经三路 
            
 
             
                10002 
                西安市太白路 
            
 
             
             
        
 
    
 
     
        ASDF 
        空ID节点啊 
        空ID节点啊 
    
 
 
----------removeAllNullIdElement()测试---------- 
16:17:32,705  INFO XmlNodeHandler:113 - 在/doc/person/adds下成功删除4了个空节点! 
16:17:32,705  INFO XmlNodeHandler:113 - 在/doc/other下成功删除3了个空节点! 
 
 
     
        某人 
         
             
                10001 
                郑州市经三路 
            
 
             
                10002 
                西安市太白路 
            
 
             
             
        
 
    
 
     
        ASDF 
         
         
    
 
 
----------Dom4j生成一个xml测试---------- 
 
haha:) 

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。放到以方便查看。 

衷心祝福广大支持和浏览熔岩博客的朋友们:周末愉快!!! 

 
在最后奉献出我亲手制作的CHM格式的“Dom4j-1.6.1 API文档”。

本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/68558,如需转载请自行联系原作者

你可能感兴趣的:(Dom4j节点处理器的实现)