合并两个XML文件在Java中 [英] Merge Two XML Files in Java

查看:295
本文介绍了合并两个XML文件在Java中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我想合并成一个文件结构相似的两个XML文件。
目前我使用 EL4J XML合并我来了横跨在本教程中。
然而,我期望它对于实例的主要问题是其不合并从两个文件合并为一个元件又名一个包含1,2,3和4不合并。
相反,它只是丢弃或1和2或3和4,这取决于文件第一次合并

所以,我将不胜感激的人谁使用XML的经验合并,如果他们能告诉我,我可能是做错了或替代没有人知道一个良好的XML API的Java,这将是能够合并文件,因为我需要的?

非常感谢您提前帮助

编辑:

真的能与这样一些很好的建议这样做增加了一个赏金。我试过jdigital的建议,但仍然有问题与XML的合并。

下面是我试图合并XML文件的结构类型的样本。

 <运行xmloutputversion =1.02>
    <信息类型=A/>
    <调试级别=0/>
    <主机开始时间=1237144741ENDTIME =1237144751>
        <状态状态=上升的理由=somereason/>
        <东西安勤=测试测试=阿尔法/>
        <目标>
            <系统名=电脑/>
        < /目标与GT;
        <结果>
            &所述;结果的id =1>
                <状态值=测试/>
                <服务价值=伽马/>
            < /&结果GT;
            &所述;结果的id =2>
                <状态值=TEST4/>
                <服务价值=gamma4/>
            < /&结果GT;
        < /结果>
        &所述;倍东西=0/>
    < /主机>
    <&RUNSTATS GT;
        <完成时间=1237144751TIMESTR =太阳报3月15日19时19分十一秒2009/>
        <导致总=0/>
    < / RUNSTATS>
< /运行><运行xmloutputversion =1.02>
    <信息类型=B/>
    <调试级别=0/>
    <主机开始时间=1237144741ENDTIME =1237144751>
        <状态状态=下降的原因=somereason/>
        <东西安勤=测试测试=阿尔法/>
        <目标>
            <系统名=电脑/>
        < /目标与GT;
        <结果>
            &所述;结果的id =3>
                <状态值=testagain/>
                <服务价值=迦玛2/>
            < /&结果GT;
            <结果ID =4>
                <状态值=testagain4/>
                <服务价值=gamma4/>
            < /&结果GT;
        < /结果>
        &所述;倍东西=0/>
    < /主机>
    <&RUNSTATS GT;
        <完成时间=1237144751TIMESTR =太阳报3月15日19时19分十一秒2009/>
        <导致总=0/>
    < / RUNSTATS>
< /运行>

期望的输出

 <运行xmloutputversion =1.02>
    <信息类型=A/>
    <调试级别=0/>
    <主机开始时间=1237144741ENDTIME =1237144751>
        <状态状态=下降的原因=somereason/>
        <状态状态=上升的理由=somereason/>
        <东西安勤=测试测试=阿尔法/>
        <目标>
            <系统名=电脑/>
        < /目标与GT;
        <结果>
            &所述;结果的id =1>
                <状态值=测试/>
                <服务价值=伽马/>
            < /&结果GT;
            &所述;结果的id =2>
                <状态值=TEST4/>
                <服务价值=gamma4/>
            < /&结果GT;
    &所述;结果的id =3>
                <状态值=testagain/>
                <服务价值=迦玛2/>
            < /&结果GT;
            <结果ID =4>
                <状态值=testagain4/>
                <服务价值=gamma4/>
            < /&结果GT;
        < /结果>
        &所述;倍东西=0/>
    < /主机>
    <&RUNSTATS GT;
        <完成时间=1237144751TIMESTR =太阳报3月15日19时19分十一秒2009/>
        <导致总=0/>
    < / RUNSTATS>
< /运行>


解决方案

不是很优雅,但你可以使用DOM解析器和XPath做到这一点:

 公共类MergeXmlDemo {  公共静态无效的主要(字串[] args)抛出异常{
    //正确的错误/异常处理不再赘述
    文件文件1 =新的文件(merge1.xml);
    文件文件2 =新的文件(merge2.xml);
    文档的DOC =合并(/运行/主机/结果,文件1,文件2);
    打印(DOC);
  }  私有静态文档合并(字符串前pression,
      文件...文件)抛出异常{
    的XPathFactory XPathFactory是否= XPathFactory.newInstance();
    XPath的XPath的= xPathFactory.newXPath();
    XPathEx pression compiledEx pression =的XPath
        .compile(如pression);
    返回合并(compiledEx pression,文件);
  }  私有静态文档合并(XPathEx pression前pression,
      文件...文件)抛出异常{
    的DocumentBuilderFactory docBuilderFactory =的DocumentBuilderFactory
        .newInstance();
    docBuilderFactory
        .setIgnoringElementContentWhitespace(真);
    的DocumentBuilder docBuilder = docBuilderFactory
        .newDocumentBuilder();
    文档基= docBuilder.parse(文件[0]);    节点结果=(节点)前pression.evaluate(基地,
        XPathConstants.NODE);
    如果(结果== NULL){
      抛出新IOException异常(文件[0]
          +:前pression不计算为节点);
    }    的for(int i = 1; I< files.length;我++){
      文档合并= docBuilder.parse(文件[I]);
      节点nextResults =(节点)前pression.evaluate(合并,
          XPathConstants.NODE);
      而(nextResults.hasChildNodes()){
        节点的孩子= nextResults.getFirstChild();
        nextResults.removeChild(孩子);
        孩子= base.importNode(小子,真);
        results.appendChild(孩子);
      }
    }    返回基地;
  }  私有静态无效打印(文档DOC)抛出异常{
    的TransformerFactory的TransformerFactory =的TransformerFactory
        .newInstance();
    变压器变压器=的TransformerFactory
        .newTransformer();
    DOMSource的源=新DOMSource的(DOC);
    结果结果=新的StreamResult(System.out的);
    transformer.transform(源,结果);
  }}

这假定您可以容纳至少两个同时RAM的文件。

I have two XML files of similar structure which I wish to merge into one file. Currently I am using EL4J XML Merge which I came across in this tutorial. However it does not merge as I expect it to for instances the main problem is its not merging the from both files into one element aka one that contains 1, 2, 3 and 4. Instead it just discards either 1 and 2 or 3 and 4 depending on which file is merged first.

So I would be grateful to anyone who has experience with XML Merge if they could tell me what I might be doing wrong or alternatively does anyone know of a good XML API for Java that would be capable of merging the files as I require?

Many Thanks for Your Help in Advance

Edit:

Could really do with some good suggestions on doing this so added a bounty. I've tried jdigital's suggestion but still having issues with XML merge.

Below is a sample of the type of structure of XML files that I am trying to merge.

<run xmloutputversion="1.02">
    <info type="a" />
    <debugging level="0" />
    <host starttime="1237144741" endtime="1237144751">
        <status state="up" reason="somereason"/>
        <something avalue="test" test="alpha" />
        <target>
            <system name="computer" />
        </target>
        <results>
            <result id="1">
                <state value="test" />
                <service value="gamma" />
            </result>
            <result id="2">
                <state value="test4" />
                <service value="gamma4" />
            </result>
        </results>
        <times something="0" />
    </host>
    <runstats>
        <finished time="1237144751" timestr="Sun Mar 15 19:19:11 2009"/>
        <result total="0" />
    </runstats>
</run>

<run xmloutputversion="1.02">
    <info type="b" />
    <debugging level="0" />
    <host starttime="1237144741" endtime="1237144751">
        <status state="down" reason="somereason"/>
        <something avalue="test" test="alpha" />
        <target>
            <system name="computer" />
        </target>
        <results>
            <result id="3">
                <state value="testagain" />
                <service value="gamma2" />
            </result>
            <result id="4">
                <state value="testagain4" />
                <service value="gamma4" />
            </result>
        </results>
        <times something="0" />
    </host>
    <runstats>
        <finished time="1237144751" timestr="Sun Mar 15 19:19:11 2009"/>
        <result total="0" />
    </runstats>
</run>

Expected output

<run xmloutputversion="1.02">
    <info type="a" />
    <debugging level="0" />
    <host starttime="1237144741" endtime="1237144751">
        <status state="down" reason="somereason"/>
        <status state="up" reason="somereason"/>
        <something avalue="test" test="alpha" />
        <target>
            <system name="computer" />
        </target>
        <results>
            <result id="1">
                <state value="test" />
                <service value="gamma" />
            </result>
            <result id="2">
                <state value="test4" />
                <service value="gamma4" />
            </result>
    	    <result id="3">
                <state value="testagain" />
                <service value="gamma2" />
            </result>
            <result id="4">
                <state value="testagain4" />
                <service value="gamma4" />
            </result>
        </results>
        <times something="0" />
    </host>
    <runstats>
        <finished time="1237144751" timestr="Sun Mar 15 19:19:11 2009"/>
        <result total="0" />
    </runstats>
</run>

解决方案

Not very elegant, but you could do this with the DOM parser and XPath:

public class MergeXmlDemo {

  public static void main(String[] args) throws Exception {
    // proper error/exception handling omitted for brevity
    File file1 = new File("merge1.xml");
    File file2 = new File("merge2.xml");
    Document doc = merge("/run/host/results", file1, file2);
    print(doc);
  }

  private static Document merge(String expression,
      File... files) throws Exception {
    XPathFactory xPathFactory = XPathFactory.newInstance();
    XPath xpath = xPathFactory.newXPath();
    XPathExpression compiledExpression = xpath
        .compile(expression);
    return merge(compiledExpression, files);
  }

  private static Document merge(XPathExpression expression,
      File... files) throws Exception {
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
        .newInstance();
    docBuilderFactory
        .setIgnoringElementContentWhitespace(true);
    DocumentBuilder docBuilder = docBuilderFactory
        .newDocumentBuilder();
    Document base = docBuilder.parse(files[0]);

    Node results = (Node) expression.evaluate(base,
        XPathConstants.NODE);
    if (results == null) {
      throw new IOException(files[0]
          + ": expression does not evaluate to node");
    }

    for (int i = 1; i < files.length; i++) {
      Document merge = docBuilder.parse(files[i]);
      Node nextResults = (Node) expression.evaluate(merge,
          XPathConstants.NODE);
      while (nextResults.hasChildNodes()) {
        Node kid = nextResults.getFirstChild();
        nextResults.removeChild(kid);
        kid = base.importNode(kid, true);
        results.appendChild(kid);
      }
    }

    return base;
  }

  private static void print(Document doc) throws Exception {
    TransformerFactory transformerFactory = TransformerFactory
        .newInstance();
    Transformer transformer = transformerFactory
        .newTransformer();
    DOMSource source = new DOMSource(doc);
    Result result = new StreamResult(System.out);
    transformer.transform(source, result);
  }

}

This assumes that you can hold at least two of the documents in RAM simultaneously.

这篇关于合并两个XML文件在Java中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆