1

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.

2
  • XPath can get you a NodeList, you could use the NodeList to build a second Document Commented Dec 16, 2014 at 5:20
  • stackoverflow.com/questions/23933442/… Or simply open xml in browser and select elements until U will get xpath as U want. Commented Dec 16, 2014 at 5:28

2 Answers 2

1

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>
Sign up to request clarification or add additional context in comments.

2 Comments

is there any way to get parents tag name so that same can be put in target document ? b'cos xml source format in not predefined in my case . thanks :)
Yes, but it depends on when you want it, you could use Node#getParent for example or you could actually get the xpath to do it
1

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

}

1 Comment

Short and sweet, beautiful working solution, thank you! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.