Create XML document using nodeList
Asked Answered
S

2

8

I need to create a XML Document object using the NodeList. Can someone pls help me to do this. This is my Java code:

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*; 
import org.w3c.dom.*;

public class ReadFile {

    public static void main(String[] args) {
        String exp = "/configs/markets";
        String path = "testConfig.xml";
        try {
            Document xmlDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(path);
            XPath xPath = XPathFactory.newInstance().newXPath();
            XPathExpression xPathExpression = xPath.compile(exp);
            NodeList nodes = (NodeList)
              xPathExpression.evaluate(xmlDocument,
                                       XPathConstants.NODESET);

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

I want to have an XML file like this:

<configs>
    <markets>   
        <market>
            <name>Real</name>
        </market>
        <market>
            <name>play</name>
        </market>
    </markets>
</configs>

Thanks in advance.

Sparge answered 26/4, 2011 at 6:48 Comment(0)
T
16

You should do it like this:

  • you create a new org.w3c.dom.Document newXmlDoc where you store the nodes in your NodeList,
  • you create a new root element, and append it to newXmlDoc
  • then, for each node n in your NodeList, you import n in newXmlDoc, and then you append n as a child of root

Here is the code:

public static void main(String[] args) {
    String exp = "/configs/markets/market";
    String path = "src/a/testConfig.xml";
    try {
        Document xmlDocument = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder().parse(path);

        XPath xPath = XPathFactory.newInstance().newXPath();
        XPathExpression xPathExpression = xPath.compile(exp);
        NodeList nodes = (NodeList) xPathExpression.
                evaluate(xmlDocument, XPathConstants.NODESET);

        Document newXmlDocument = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder().newDocument();
        Element root = newXmlDocument.createElement("root");
        newXmlDocument.appendChild(root);
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            Node copyNode = newXmlDocument.importNode(node, true);
            root.appendChild(copyNode);
        }

        printTree(newXmlDocument);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public static void printXmlDocument(Document document) {
    DOMImplementationLS domImplementationLS = 
        (DOMImplementationLS) document.getImplementation();
    LSSerializer lsSerializer = 
        domImplementationLS.createLSSerializer();
    String string = lsSerializer.writeToString(document);
    System.out.println(string);
}

The output is:

<?xml version="1.0" encoding="UTF-16"?>
<root><market>
            <name>Real</name>
        </market><market>
            <name>play</name>
        </market></root>

Some notes:

  • I've changed exp to /configs/markets/market, because I suspect you want to copy the market elements, rather than the single markets element
  • for the printXmlDocument, I've used the interesting code in this answer

I hope this helps.


If you don't want to create a new root element, then you may use your original XPath expression, which returns a NodeList consisting of a single node (keep in mind that your XML must have a single root element) that you can directly add to your new XML document.

See following code, where I commented lines from the code above:

public static void main(String[] args) {
    //String exp = "/configs/markets/market/";
    String exp = "/configs/markets";
    String path = "src/a/testConfig.xml";
    try {
        Document xmlDocument = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder().parse(path);

        XPath xPath = XPathFactory.newInstance().newXPath();
        XPathExpression xPathExpression = xPath.compile(exp);
        NodeList nodes = (NodeList) xPathExpression.
        evaluate(xmlDocument,XPathConstants.NODESET);

        Document newXmlDocument = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder().newDocument();
        //Element root = newXmlDocument.createElement("root");
        //newXmlDocument.appendChild(root);
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            Node copyNode = newXmlDocument.importNode(node, true);
            newXmlDocument.appendChild(copyNode);
            //root.appendChild(copyNode);
        }

        printXmlDocument(newXmlDocument);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

This will give you the following output:

<?xml version="1.0" encoding="UTF-16"?>
<markets>   
        <market>
            <name>Real</name>
        </market>
        <market>
            <name>play</name>
        </market>
    </markets>
Telephotography answered 26/4, 2011 at 7:50 Comment(3)
it works fine Marco. But the problem is there is element called root which is not orginally in the xml document. Is there a way to do it without having the root element. Thanks in advanceSparge
well, you need a root element in an XML. What you might do is extract markets with your original XPath (String exp = "/configs/markets";), and then your NodeList will contain a single node, which can directly import and append to your new XML document: see edited answer.Telephotography
@Telephotography Is there any way of retaining the all the ancestor nodes also, while copying/cloning an XML Node ?Ssr
R
0

you can try the adoptNode() method of Document.

Maybe you will need to iterate over your NodeList. You can access the individual Nodes with nodeList.item(i).

If you want to wrap your search results in an Element, you can use createElement() from the Document and appendChild() on the newly created Element

Remodel answered 26/4, 2011 at 6:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.