Get XML child node from parent node using XPATH java

341 Views Asked by At

I'm trying to get specific child node from list of nodes using xpath.

Here is my xml input

<root>
    <Transaction>
        <code> 123 </code>
        <Reason> test1 </Reason>
    </Transaction>
    <Transaction>
        <code> 456 </code>
    </Transaction>
    <Transaction>
        <code> 789 </code>
        <Reason> test2 </Reason>
    </Transaction>
</root> 

I'm trying to get all the transactions as node list and then check one by one inside each trancation either it has reason or not all using Xpath. Here is my sample code.

    Document document = builder.parse(new FileInputStream(file));

    XPath xPath = XPathFactory.newInstance().newXPath();

    //Get all the transactions
    NodeList nodeList = (NodeList) xPath.evaluate("//Transaction", document, XPathConstants.NODESET);
    
    
    for (int temp = 0; temp < nodeList.getLength(); temp++) {

        Node node = nodeList.item(temp);
        Element element = (Element) node;
        
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            XPath xPath2 = XPathFactory.newInstance().newXPath();
            
            //This one always return first value
            Node child = (Node) xPath2.evaluate("//Reason", node, XPathConstants.NODE);
            
            if(child != null) {
                System.out.println(child.getTextContent());
            }
            
            //This is working as expected
            if(element.getElementsByTagName("Reason").getLength() > 0) {
                System.out.println(element.getElementsByTagName("Reason").item(0).getTextContent());
            }

        }
    }

If I cast the node to element and try to get child element by tag name it's working fine. But when I try to do it using X-PAth it returns all the values from other nodes as well.

1

There are 1 best solutions below

0
Conal Tuohy On

There's no need to execute the loop in Java; you can do it in the XPath expression itself:

//Transaction[Reason]

That XPath will return you all the Transaction elements which have a child Reason element.

If you want to get the Reason elements which are children of a Transaction element, then use this XPath:

//Transaction/Reason

If you want to get all the text nodes which are children of Reason elements which are children of a Transaction element, then use this XPath:

//Transaction/Reason/text()