Объединение xml-файла с помощью Java NodeList

Я пытаюсь объединить два xml-файла, как показано ниже, но я не могу получить желаемый результат, пожалуйста, помогите мне спасибо

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

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

File2.в XML

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

выходной ток:

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

Ожидаемый Результат:

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

3 ответов


для того, чтобы сделать это самостоятельно. Вы должны сделать это следующим образом :

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();
    }


}

окончательный выход 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>

Как вы хотите его ;-)

надеюсь, это поможет,


это решение для файлов, где вам нужно повторить и проверить что-то перед слиянием.

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-код:

    <?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>

результат.в 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 программа для этого:

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;
    }
}

проблема в том, что вы хотите добавить дочерние элементы к элементу "персонал", но на самом деле вы делаете :

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

означает, что вы ищете родительский узел одного из" штатных " узлов списка, и этот узел является "компанией". Таким образом, вы добавляете новый узел "персонал" (тот, который импортирован из doc1) в узел "компания" doc

теперь, что вы хотите сделать, это перебрать дочерние узлы doc1" staff "и добавить их один за другим к узлу" staff " doc. Так вы хотелось бы изменить определение nodes1 следующим образом:

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

затем измените узел, который вы добавляете, заменив

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

by

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

Итак, теперь вы будете добавлять все дочерние узлы "персонал" ( / !\ только для первого элемента "персонал") doc1 к первому элементу" персонал " doc

Примечание 1: Не используйте переменную итерации (i), которую вы используете для запуска списка A, чтобы выбрать элемент другого списка, если вы не знаете, что делаете (для примере оба списка имеют одинаковую длину)

примечание 2: это решение добавит узлы первого элемента" персонал "doc1 к первому элементу" персонал " doc. Возможно, вы захотите добавить несколько итераций здесь и там.