使用java NodeList合并xml文件

[英]Merging xml file using java NodeList


I'm trying to merge two xml files as shown below but i can't able to get the desired output please help me thank you

我正在尝试合并两个xml文件,如下所示,但我无法获得所需的输出请帮助我谢谢

Java code:

Java代码:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();   
domFactory.setIgnoringComments(true);  
DocumentBuilder builder = domFactory.newDocumentBuilder();   
Document doc = builder.parse(new File("file1.xml"));   
Document doc1 = builder.parse(new File("file2.xml"));   

NodeList nodes = doc.getElementsByTagName("staff");  

NodeList nodes1 = doc1.getElementsByTagName("staff");

for(int i=0;i<nodes1.getLength();i=i+1){  

Node n= (Node) doc.importNode(nodes1.item(i), true);  
nodes.item(i).getParentNode().appendChild(n);

}  

Transformer transformer = TransformerFactory.newInstance().newTransformer();  
transformer.setOutputProperty(OutputKeys.INDENT, "yes");  

StreamResult result = new StreamResult(new StringWriter());  
DOMSource source = new DOMSource(doc);  
transformer.transform(source, result);  
Writer output = null;
output = new BufferedWriter(new FileWriter("mergedxml.xml"));

String xmlOutput = result.getWriter().toString();  
output.write(xmlOutput);
output.close();
System.out.println("merge complete");

File1.xml

File1.xml

    <company>
        <staff>
            <name>john</name>
            <phone>465456433</phone>
            <email>gmail1</email>
        </staff>
    </company>

File2.xml

File2.xml

    <company>
        <staff>
            <area>area1</area>
            <city>city1</city>
        </staff>
    </company>

Current output:

当前输出:

    <company>
        <staff>
            <name>john</name>
            <phone>465456433</phone>
            <email>gmail1</email>
        </staff>
        <staff>
            <area>area1</area>
            <city>city1</city>
        </staff>
    </company>

Expected Output:

预期产出:

    <company>
        <staff>
            <name>john</name>
            <phone>465456433</phone>
            <email>gmail1</email>
            <area>area1</area>
            <city>city1</city>
        </staff>
    </company>

3 个解决方案

#1


5  

In order to do that on your own. You should do this following :

为了自己做到这一点。你应该这样做:

public static void mergeXML(){


    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = null;
    Document doc = null;
    Document doc2 = null;

    try {
            db = dbf.newDocumentBuilder();
            doc = db.parse(new File("D:\\Loic_Workspace\\Test2\\res\\test.xml"));
            doc2 = db.parse(new File("D:\\Loic_Workspace\\Test2\\res\\test2.xml"));
            NodeList ndListFirstFile = doc.getElementsByTagName("staff");

            Node nodeArea = doc.importNode(doc2.getElementsByTagName("area").item(0), true);
            Node nodeCity = doc.importNode(doc2.getElementsByTagName("city").item(0), true);
            ndListFirstFile.item(0).appendChild(nodeArea);
            ndListFirstFile.item(0).appendChild(nodeCity);

          TransformerFactory tFactory = TransformerFactory.newInstance();
          Transformer transformer = tFactory.newTransformer();
          transformer.setOutputProperty(OutputKeys.INDENT, "yes");  

          DOMSource source = new DOMSource(doc);
          StreamResult result = new StreamResult(new StringWriter());
          transformer.transform(source, result); 

          Writer output = new BufferedWriter(new FileWriter("D:\\Loic_Workspace\\Test2\\res\\testFinal.xml"));
          String xmlOutput = result.getWriter().toString();  
          output.write(xmlOutput);
          output.close();

    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (TransformerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

Final output of testFinal.xml :

testFinal.xml的最终输出:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<company>
 <staff>
 <name>john</name>
 <phone>465456433</phone>
 <email>gmail1</email>
 <area>area1</area>
<city>city1</city>
</staff>
 </company>

As you want it ;-)

如你所愿;-)

Hope it helps,

希望能帮助到你,

#2


1  

This solution is for files where you need to iterate and verify something before to merge.

此解决方案适用于需要在合并之前进行迭代和验证的文件。

file1.xml:

file1.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <reactions>
        <reaction>
            <ID>07402</ID>
            <type>irreversible</type>
            <substrate>15666</substrate>
            <product>07756</product>
        </reaction>
        <reaction>
    <ID>03063</ID>
    <type>irreversible</type>
    <substrate>00916</substrate>
    <product>04712</product>
</reaction>

file2.xml:

file2.xml:

    <?xml version="1.0" encoding="UTF-8"?><reactions>
    <reaction>
        <ID>00001</ID>
        <reactionName>polyphosphate polyphosphohydrolase</reactionName>
        <reactionDescription> Polyphosphate + n H2O &lt;=&gt; (n+1) Oligophosphate</reactionDescription>
    </reaction>
    <reaction>
        <ID>00002</ID>
        <reactionName>Reduced ferredoxin:dinitrogen oxidoreductase (ATP-hydrolysing)</reactionName>
        <reactionDescription> 16 ATP + 16 H2O + 8 Reduced ferredoxin &lt;=&gt; 8 e- + 16 Orthophosphate + 16 ADP + 8 Oxidized ferredoxin</reactionDescription>
    </reaction>    
    <reaction>
        <ID>03063</ID>
        <reactionName>cephalosporin-C:2-oxoglutarate aminotransferase</reactionName>
        <reactionDescription> Cephalosporin C + 2-Oxoglutarate &lt;=&gt; (7R)-7-(5-Carboxy-5-oxopentanoyl)aminocephalosporinate + D-Glutamate</reactionDescription>
    </reaction>
    <reaction>
        <ID>07402</ID>
        <reactionName>(7R)-7-(4-carboxybutanamido)cephalosporanate amidohydrolase</reactionName>
        <reactionDescription> (7R)-7-(4-Carboxybutanamido)cephalosporanate + H2O &lt;=&gt; 7-Aminocephalosporanic acid + Glutarate</reactionDescription>
    </reaction>  
</reactions>

Result.xml

为result.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<reactions>
    <reaction>
        <ID>07402</ID>
        <type>irreversible</type>
        <substrate>15666</substrate>
        <product>07756</product>
    <reactionName>(7R)-7-(4-carboxybutanamido)cephalosporanate amidohydrolase</reactionName>
<reactionDescription> (7R)-7-(4-Carboxybutanamido)cephalosporanate + H2O &lt;=&gt; 7-Aminocephalosporanic acid + Glutarate</reactionDescription>
</reaction>
    <reaction>
        <ID>03063</ID>
        <type>irreversible</type>
        <substrate>00916</substrate>
        <product>04712</product>
    <reactionName>cephalosporin-C:2-oxoglutarate aminotransferase</reactionName>
<reactionDescription> Cephalosporin C + 2-Oxoglutarate &lt;=&gt; (7R)-7-(5-Carboxy-5-oxopentanoyl)aminocephalosporinate + D-Glutamate</reactionDescription>
</reaction>
</reactions>

Java program to do this:

Java程序执行此操作:

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class MergeXML {

    public static void main(String[] args) {
        MergeXML m = new MergeXML();
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

            DocumentBuilder db;

            db = dbf.newDocumentBuilder();

            Document secondaryMetabolismXML = db
                    .parse(new File("/home/bioinfo/workspace/teste/src/file1.xml"));
            Document generalMetabolismXML = db
                    .parse(new File("/home/bioinfo/workspace/teste/src/file2.xml"));

            NodeList secondaryReactions = secondaryMetabolismXML.getElementsByTagName("reaction");
            NodeList generalReactions = generalMetabolismXML.getElementsByTagName("reaction");

            for (int s = 0; s < secondaryReactions.getLength(); s++) {
                Node secondaryReaction = secondaryReactions.item(s);
                for (int g = 0; g < generalReactions.getLength(); g++) {
                    Node generalReaction = generalReactions.item(g);
                    if (getChildrenByNodeName(secondaryReaction, "ID").getTextContent()
                            .equals(getChildrenByNodeName(generalReaction, "ID").getTextContent())) {
                        if (getChildrenByNodeName(generalReaction, "reactionName") != null) {
                            secondaryReaction.appendChild(secondaryMetabolismXML
                                    .importNode(getChildrenByNodeName(generalReaction, "reactionName"), true));
                        }
                        if (getChildrenByNodeName(generalReaction, "reactionAlternativeName") != null) {
                            secondaryReaction.appendChild(secondaryMetabolismXML.importNode(
                                    getChildrenByNodeName(generalReaction, "reactionAlternativeName"), true));
                        }
                        if (getChildrenByNodeName(generalReaction, "reactionDescription") != null) {
                            secondaryReaction.appendChild(secondaryMetabolismXML
                                    .importNode(getChildrenByNodeName(generalReaction, "reactionDescription"), true));
                        }
                    }
                }
            }
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");

            DOMSource source = new DOMSource(secondaryMetabolismXML);
            StreamResult result = new StreamResult(new StringWriter());
            transformer.transform(source, result);

            Writer output = new BufferedWriter(
                    new FileWriter("/home/bioinfo/workspace/teste/src/Result.xml"));
            String xmlOutput = result.getWriter().toString();
            output.write(xmlOutput);
            output.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * Returns a node child when you have a match with a given node name
     * 
     * @param node
     * @param nodeName
     * @return
     */
    public static Node getChildrenByNodeName(Node node, String nodeName) {
        for (Node childNode = node.getFirstChild(); childNode != null;) {
            Node nextChild = childNode.getNextSibling();
            if (childNode.getNodeName().equalsIgnoreCase(nodeName)) {
                return childNode;
            }
            childNode = nextChild;
        }
        return null;
    }
}

#3


0  

Problem is, you want to append child elements to "staff" element but what you actually do is :

问题是,你想将子元素附加到“staff”元素,但你实际做的是:

nodes.item(i).getParentNode().appendChild(n);

meaning you're looking for the parent node of one of the "staff" nodes of the list, and that node is "company". So you're appending a new "staff" node (the one imported from doc1) to the "company" node of doc

这意味着您正在寻找列表中某个“staff”节点的父节点,该节点是“company”。因此,您要将新的“staff”节点(从doc1导入的节点)附加到doc的“company”节点

Now, what you want to do is to iterate over "staff" child nodes of doc1 and to append them one by one to the "staff" node of doc. So you would want to change nodes1 definition as following :

现在,您要做的是迭代doc1的“staff”子节点,并将它们逐个附加到doc的“staff”节点。所以你想要更改nodes1定义如下:

// Retrieving child nodes of first "staff" element of doc1
NodeList nodes1 = doc1.getElementsByTagName("staff").item(0).getChildNodes();

Then change the node you append that to by replacing

然后通过替换更改您追加的节点

nodes.item(i).getParentNode().appendChild(n);

by

通过

nodes.item(0).appendChild(n);

So now you'll be appending all "staff" child nodes (/!\ only for the first "staff" element) of doc1 to the first "staff" element of doc

所以现在你要将doc1的所有“staff”子节点(/!\仅用于第一个“staff”元素)附加到doc的第一个“staff”元素

Note 1 : Dont use the iteration variable (i) you use to run through list A to select an item of another list unless you're aware of what you're doing (for example both lists are of the same length)

注1:不要使用迭代变量(i)来运行列表A来选择另一个列表的项目,除非你知道你正在做什么(例如两个列表的长度相同)

Note 2 : That solution will append the nodes of first "staff" element of doc1 to the first "staff" element of doc. You will maybe want to add some iterations here and there.

注意2:该解决方案将doc1的第一个“staff”元素的节点附加到doc的第一个“staff”元素。您可能希望在此处添加一些迭代。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2013/01/28/dc743b4272e400dfbc6d4e88b2c1e684.html



 
© 2014-2018 ITdaan.com 粤ICP备14056181号