当前位置:  开发笔记 > 编程语言 > 正文

用Java合并两个XML文件

如何解决《用Java合并两个XML文件》经验,为你挑选了2个好方法。

我有两个结构相似的XML文件,我希望将它们合并到一个文件中.目前我正在使用本教程中遇到的EL4J XML Merge.然而它没有合并,因为我期望它的实例主要问题是它没有将两个文件合并为一个元素,即包含1,2,3和4的元素.相反,它只丢弃1和2或3和4取决于首先合并的文件.

所以我会感谢任何有XML Merge经验的人,如果他们能告诉我我可能做错了什么,或者有人知道一个优秀的XML API for Java能够按我的要求合并文件吗?

非常感谢您的帮助

编辑:

真的可以做一些关于这样做的好建议,所以增加了赏金.我已经尝试过jdigital的建议,但仍然遇到XML合并的问题.

下面是我尝试合并的XML文件结构类型的示例.


    
    
    
        
        
        
            
        
        
            
                
                
            
            
                
                
            
        
        
    
    
        
        
    



    
    
    
        
        
        
            
        
        
            
                
                
            
            
                
                
            
        
        
    
    
        
        
    

预期产出


    
    
    
        
        
        
        
            
        
        
            
                
                
            
            
                
                
            
            
                
                
            
            
                
                
            
        
        
    
    
        
        
    

McDowell.. 11

不是很优雅,但您可以使用DOM解析器和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);
  }

}

这假设您可以同时在RAM中保存至少两个文档.



1> McDowell..:

不是很优雅,但您可以使用DOM解析器和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);
  }

}

这假设您可以同时在RAM中保存至少两个文档.



2> stwissel..:

我使用XSLT来合并XML文件.它允许我调整合并操作,只是将内容一起猛击或在特定级别合并.这是一个更多的工作(和XSLT语法是一种特殊的),但超级灵活.这里需要你做的一些事情

a)包含一个附加文件b)复制原始文件1:1 c)设计合并点,有或没有避免重复

a)一开始我有

yoursecondfile.xml

这允许使用$ mDoc指向第二个文件

b)复制源树1:1的说明是2个模板:



    
         
        
    



    

没有其他任何东西你得到你的第一个源文件的1:1副本.适用于任何类型的XML.合并部分是特定于文件的.让我们假设你有一个带有事件ID属性的事件元素.您不需要重复的ID.模板看起来像这样:

 
    
    
        
        
        
        
            
            
                
                    
                    
                
            
        
    

当然,您可以比较标签名称等其他内容.此外,由您决定合并的深度.如果您没有要比较的密钥,则构造变得更容易,例如对于日志:

 
     
          
          
          
    

要在Java中运行XSLT,请使用以下命令:

    Source xmlSource = new StreamSource(xmlFile);
    Source xsltSource = new StreamSource(xsltFile);
    Result xmlResult = new StreamResult(resultFile);
    TransformerFactory transFact = TransformerFactory.newInstance();
    Transformer trans = transFact.newTransformer(xsltSource);
    // Load Parameters if we have any
    if (ParameterMap != null) {
       for (Entry curParam : ParameterMap.entrySet()) {
            trans.setParameter(curParam.getKey(), curParam.getValue());
       }
    }
    trans.transform(xmlSource, xmlResult);

或者您下载Saxon SAX Parser并从命令行执行(Linux shell示例):

#!/bin/bash
notify-send -t 500 -u low -i gtk-dialog-info "Transforming $1 with $2 into $3 ..."
# That's actually the only relevant line below
java -cp saxon9he.jar net.sf.saxon.Transform -t -s:$1 -xsl:$2 -o:$3
notify-send -t 1000 -u low -i gtk-dialog-info "Extraction into $3 done!"

因人而异


源xmlSource = new StreamSource(xmlFile); 源xsltSource = new StreamSource(xsltFile); 结果xmlResult = new StreamResult(resultFile); TransformerFactory transFact = TransformerFactory.newInstance(); Transformer trans = transFact.newTransformer(xsltSource); //加载参数,如果我们有任何如果(parameterMap的!= NULL){对于(条目<字符串,字符串> curParam:ParameterMap.entrySet()){trans.setParameter(curParam.getKey(),curParam.getValue()); trans.transform(xmlSource,xmlResult);
推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有