Jitendra
Jitendra

Reputation: 1203

How to get a part of xml using xpath in java

based on xpath i want to select a part of xml and selected part i want to use as another xml source.

e.g:

 <root>
    <a type="t1">
        <property name="data" value="val1"/>
    </a>
    <a type="t2">
        <property name="data" value="val2"/>
    </a>
   <a type="t1">
        <property name="data" value="val2"/>
    </a>
 </root>

xpath : /root/a[@type="t1"]/

and selected xml would be

<root>
    <a type="t1">
        <property name="data" value="val1"/>
    </a>
    <a type="t1">
        <property name="data" value="val2"/>
    </a>
 </root>

same i want to use as another xml source in java. Please help me out.

Upvotes: 1

Views: 4238

Answers (2)

Hemant Thorat
Hemant Thorat

Reputation: 2456

Following function can be used to extract xml block as string by passing proper xpath expression,

    private static String nodeToString(Node node) throws TransformerException
{
    StringWriter buf = new StringWriter();
    Transformer xform = TransformerFactory.newInstance().newTransformer();
    xform.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    xform.transform(new DOMSource(node), new StreamResult(buf));
    return(buf.toString());
}

    public static void main(String[] args) throws Exception
{
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(inputFile);

        XPath xPath = XPathFactory.newInstance().newXPath();
        Node result = (Node)xPath.evaluate("A/B/C", doc, XPathConstants.NODE); //"A/B[id = '1']" //"//*[@type='t1']"

        System.out.println(nodeToString(result));

}

Upvotes: 1

MadProgrammer
MadProgrammer

Reputation: 347204

Load the XML and find the nodes you are looking for...

DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
Document d = b.parse(...);

// Find all nodes with the attribute of type equal to `t1`
// You could use //*/a[@type='t1'] if you wanted to narrow it down
// This find ALL matches through out the document...
String expression = "//*[@type='t1']";
XPath xPath = XPathFactory.newInstance().newXPath();
Object result = xPath.compile(expression).evaluate(d, XPathConstants.NODESET);

NodeList nodes = (NodeList) result;

Create a new Document....

Document d2 = b.newDocument();
Element root = d2.createElement("root");
d2.appendChild(root);

Add the nodes from the first to the second...

for (int i = 0; i < nodes.getLength(); i++) {
    Node node = nodes.item(i);
    d2.adoptNode(node);
    root.appendChild(node);
}

Which should result in...

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
    <a type="t1">
        <property name="data" value="val1"/>
    </a>
    <a type="t1">
        <property name="data" value="val2"/>
    </a>
</root>

Upvotes: 1

Related Questions