例如:有2个xml文件。 a.xml和b.xml 把b.xml和a对比,如果相同则不覆盖如果不同,则吧不同的复制过去形成新的a.xml文件a.xml:<conf>
<performance>CPU_USED_PERCENT</performance>
<evtConf>  
   <evt col="DVC_NAME" id="A" key="DVC_NAME" name="设备名称"/>
   <evt col="DVC_TYPE" id="b" key="DVC_TYPE" name="设备类型"/>
</evtConf> 
<collect>     
    <dev ip="10.1.128.53" isOnsite="true" type="FW"> 
      <dvc_att key="checked"/>  
      <att> 
        <attention name="H" value="0"/>  
        <attention name="I" value="0"/>  
        <attention name="L" value="0"/> 
    </dev>      
  </collect>   
</conf>b.xml
<conf>
<performance>CPU_USED_PERCENT</performance>
<evtConf>  
   <evt col="DVC_NAME" id="A" key="DVC_NAME" name="设备名称"/>
   <evt col="DVC_TYPE" id="b" key="DVC_TYPE" name="设备类型"/>
</evtConf> 
<collect>     
    <dev ip="10.1.128.225" isOnsite="true" type="FW"> 
      <dvc_att key="checked"/>  
      <att> 
        <attention name="H" value="0"/>  
        <attention name="I" value="0"/>  
        <attention name="L" value="0"/> 
    </dev>      
  </collect>   
</conf>
最后合并成这样的:<conf>
<performance>CPU_USED_PERCENT</performance>
<evtConf>  
   <evt col="DVC_NAME" id="A" key="DVC_NAME" name="设备名称"/>
   <evt col="DVC_TYPE" id="b" key="DVC_TYPE" name="设备类型"/>
</evtConf> 
<collect>   
<dev ip="10.1.128.53" isOnsite="true" type="FW"> 
      <dvc_att key="checked"/>  
      <att> 
        <attention name="H" value="0"/>  
        <attention name="I" value="0"/>  
        <attention name="L" value="0"/> 
    </dev>    
    <dev ip="10.1.128.225" isOnsite="true" type="FW"> 
      <dvc_att key="checked"/>  
      <att> 
        <attention name="H" value="0"/>  
        <attention name="I" value="0"/>  
        <attention name="L" value="0"/> 
    </dev>         
  </collect>   
</conf>
求高手给思路,最好能有代码说明下,万分感谢!!

解决方案 »

  1.   

    a、b全读到内存,比较后生成新的a.xml
      

  2.   

    先算hash 一样就不改 不同的时候再修正,直接用map存放 可以省事的去重复。
      

  3.   

    用dom去操作xml文件,具体代码去看help文档。
      

  4.   

    需求没说清楚啊,通常粗略看过去很容易就认为/conf/collect/dev/@ip不想等,则其父节点计为新节点,需要合并!但是如果IP相等呢?那用A的还是用B的?
    所谓重复,只针对/conf/collect/dev节点而言me?evtConf之类的节点不做重复判断?两个都有同名节点时,以谁为准?不管需求是怎样的,我给你提个思路吧:dom4j+jaxen,通过xpath来完成
    首先检索b.xml种的所有/conf/collect/dev,依次迭代所有@ip,然后依次从a.xml中删除/conf/collect/dev[@ip='b.xml中的每个ip'],最后一次性向a.xml的/conf/collect添加所有b.xml中的所有/conf/collect/dev!
      

  5.   


    不是这样的,只要是他们中间的某一个拣点的内容不一样,就需要修改,当然,这里可以写成dev 不相同则修改。前面的基本都是固定的,不会发生变化。
      

  6.   


    怎么 判断两个文件的NODE是否相同呢
      

  7.   


    做法都类似,那你标题就不应该是叫两个文件合并,至少是覆盖!假设先有a.xml,然后用b.xml覆盖a.xml
    使用XPath在b.xml上查询//*,那么b.xml的一切都将作为一个列表返回,迭代时,每个Node可通过 getUniquePath获取路径,依次判断a.xml是否存在该路径,不存在则添加,存在的话该修改就修改!
      

  8.   

    如果结构一样还是挺简单的
    先把a.xml和b.xml写到2个实体类里面  在进行比较  合并  
    最后写到c.xml里面
      

  9.   

    dom4j+jaxen  public static void main(String...args) throws Exception{
        SAXReader saxReader=new SAXReader();
        Document a=saxReader.read(new File("a.xml"));
        Document b=saxReader.read(new File("b.xml"));
        List<Element> elements=b.selectNodes("/conf/collect/dev");
        Element parent=(Element)a.selectSingleNode("/conf/collect");
        for(Element element:elements){
          String ip=element.attributeValue("ip");
          Element old=(Element)a.selectSingleNode("/conf/collect/dev[@ip='"+ip+"']");
          if(old!=null) parent.remove(old);
          parent.add(element.detach());
        }
        System.out.println(a.asXML());
      }在你进一步提出你更详细的需求细节时,先考虑以下两点:
    1:定义出你所谓的“如果相同”,何为相同?两个xml中同路径的dev节点名相同算相同么?还是其属性ip相同才算?还是更多的属性需要相同?或者所有属性要求相同,还是连同其子元素及其子孙元素及其属性相同才算相同?
    2:如果不同是不是直接添加?如果相同是直接摘除原来的挂上新的?还是要一层层打开子元素挨个判断?如果依次迭代判断又需要再次定义其子孙元素的“如果相同”。