dom4j合并xml报文

dom4j合并xml报文

报文转换思想:
先将报文最长转化为dom对象
再将报文进行对比不存在的就新增进去
原dom对象xml报文:

<?xml version="1.0" encoding="utf-8"?>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">  
  <soapenv:Body> 
    <hgwTerminalRestartResponse xmlns="http://www.example.org/MobileLoadingMachine/">  
      <responseStr xmlns="">&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;root&gt;&lt;resultCode&gt;3&lt;/resultCode&gt;&lt;/root&gt;</responseStr> 
    </hgwTerminalRestartResponse> 
  </soapenv:Body> 
</soapenv:Envelope>

例如要合并的doc2

<?xml version="1.0" encoding="utf-8"?>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
  <soapenv:Body id="1"> 
    <hgwTerminalRestartResponse xmlns="http://www.example.org/MobileLoadingMachine/">  
      <responseStr xmlns="">&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;root&gt;&lt;resultCode&gt;3&lt;/resultCode&gt;&lt;/root&gt;</responseStr> 
    </hgwTerminalRestartResponse>  
    <sss xmlns="http://www.example.org/MobileLoadingMachine/">  
      <responseStr xmlns="">&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;root&gt;&lt;resultCode&gt;3&lt;/resultCode&gt;&lt;/root&gt;</responseStr> 
    </sss> 
  </soapenv:Body> 
</soapenv:Envelope>

先将2个xml报文转为doc对象:

Document doc = null ;
        try {
            doc = DocumentHelper.parseText(str);
            System.out.println("=================="+ doc.asXML());

        }catch(DocumentException e){

        }

        //打印所有college节点值,如果有的话
        Document doc1 = null ;
        try {
            doc1 = DocumentHelper.parseText(str1);
            System.out.println("=================="+ doc1.asXML());

        }catch(DocumentException e){

        }

然后在将其对比取根目录对比

 /**
     * 
     * @param oridoc 旧的文档对象
     * @param newdoc 新的文档对象
     */

 public static void compare(Document oridoc,Document newdoc){


        Element oriRootElement = oridoc.getRootElement();
        Element newRootElement = newdoc.getRootElement();

        if(oriRootElement.getQualifiedName().equals(newRootElement.getQualifiedName())){
               addAttrAndName( oriRootElement, newRootElement);

            for(Iterator<Element> sonElement = newRootElement.elementIterator() ; sonElement.hasNext();) {
                Element son = sonElement.next();

                Element element= oriRootElement.element(son.getQName());

                if(element==null){
                    oriRootElement.add((Element) son.clone());
                    return;
                }
                List<String> nodeList = new ArrayList<String>();
                Set<String> pathSet = new HashSet<String>();
                leafXmlCompare(son,element);
            }
        }

    };
    /**
     * 
     * @param oriRootElement 旧的元素
     * @param newElement 新的元素
     */
 public static void addAttrAndName(Element oriRootElement,Element newElement){

        //获取所有的命名空间
        for( Object ob :newElement.content() )
            if( ob instanceof  Namespace) {
                System.out.println("  ##Namespace:"+ ((Namespace) ob).getPrefix());
                Namespace namespace= oriRootElement.getNamespaceForPrefix(((Namespace) ob).getPrefix());
                if(namespace==null){
                    oriRootElement.add(((Namespace) ob));
                }
            }
        //获取所有的属性
        for(Object obj :newElement.attributes() )
            if( obj instanceof  Attribute) {
                Attribute newAttribute= (Attribute) obj;
                Attribute oriAttribute= oriRootElement.attribute(newAttribute.getQName());
                if(oriAttribute==null){
                    oriRootElement.add((Attribute) newAttribute.clone());
                }
            }
    }

判断子元素是否存在不存在的直接新增到旧的报文对象去,注意这里新增dom4j要用clone()方法才行,
在判断命名空间和属性是否存在,新的存在在遍历新的命名空间和属性,如果对应的旧的不存在就新增进去
同理下面就遍历到子节点

/**
     * XML的Element路径遍历获取
     * @param element 新的当前节点元素
     *  @param oriElement 旧的当前节点元素              
     */
    private static void leafXmlCompare(Element element, Element oriElement){
        addAttrAndName( oriElement, element);
        if(element.isTextOnly()){
            return;
        }else if(StringUtils.isNotBlank(element.getText())){
            
            return;
        }
        for(Iterator<Element> sonElement = element.elementIterator() ; sonElement.hasNext();) {

            Element son = sonElement.next();
            Element element1= oriElement.element(son.getQName());

            System.out.println("=========="+son.getQName());
            System.out.println("=========="+son.getQualifiedName());

            if(element1==null){
                System.out.println("=========="+oriElement.getQualifiedName());
                oriElement.add((Element) son.clone());
                return;
            }
            leafXmlCompare(son,element1);
        }
    }

根据递归方法遍历新的报文最后遍历到文本停止:如果旧的不存在新的节点就新增进去。最后就是合并的新的报文。如果json的话也可以按照这个,转换成json对象。不过这里我转换json比较复杂不是用xml的方式,后续可参考我写的json合并报文。
最终实现的效果打印出来:
在这里插入图片描述
至于求报文节点的结构的可以将合并的报文:

 /**
     * XML的Element路径遍历获取
     * @param element 当前节点元素
     * @param nodeList  全部路径节点集合
     * @param pathSet 用于节点去重
     */
    private static void leafXml(Element element, List<String> nodeList, Set<String> pathSet,String qualifiedName){
        // 数组节点不重复保存



        System.out.println("==================");
        System.out.println("==================");
        List<String> sss=element.attributes();
        System.out.println("//sss:"+element.getNodeType());
        List<Attribute> attributes = element.attributes();
        //打印属性
        for (Attribute attr : attributes) {
            System.out.println(attr.getName()+":"+attr.getValue());
        }

        System.out.println("//telephone:getName:"+element.getName());
        System.out.println("  ##getNodeType:"+element.getNodeType());
        System.out.println("  ##getTextTrim:"+element.getTextTrim());
        System.out.println("  ##getNamespaceURI:"+element.getNamespaceURI());
        System.out.println("  ##getNodeTypeName:"+element.getNodeTypeName());
        System.out.println("  ##getQualifiedName:"+element.getQualifiedName());
        System.out.println("  ##getUniquePath:"+element.getUniquePath());
        System.out.println("  ##getPath:"+element.getPath());
        String  lastChar = element.getUniquePath().substring(element.getUniquePath().length() - 3); // => "1"
        System.out.println("  ##lastChar:"+lastChar);
        if(lastChar.contains("[1]")){
            qualifiedName=qualifiedName+"/"+element.getQualifiedName()+lastChar;
        }else if(lastChar.contains("[2]")){
            qualifiedName=qualifiedName+"/"+element.getQualifiedName()+lastChar;
        }else if(lastChar.contains("[3]")){
            qualifiedName=qualifiedName+"/"+element.getQualifiedName()+lastChar;
        }else if(lastChar.contains("[4]")){
            qualifiedName=qualifiedName+"/"+element.getQualifiedName()+lastChar;
        }else{
            qualifiedName=qualifiedName+"/"+element.getQualifiedName();
        }
        System.out.println("  ##qualifiedName:"+qualifiedName);
        if(element.isTextOnly()){
            if(!pathSet.contains(element.getPath())){
                nodeList.add(element.getUniquePath());
                pathSet.add(element.getPath());
            }
            return;
        }else if(StringUtils.isNotBlank(element.getText())){
            if(!pathSet.contains(qualifiedName)){
                nodeList.add(qualifiedName);
                pathSet.add(qualifiedName);
            }
            return;
        }
        for(Iterator<Element> sonElement = element.elementIterator() ; sonElement.hasNext();) {

            Element son = sonElement.next();

            leafXml(son,nodeList,pathSet,qualifiedName);
        }
    }

然后用这个nodeList求出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值