Showing posts with label xpath. Show all posts
Showing posts with label xpath. Show all posts

Thursday, 7 August 2014

XPATH to check if a given node is present or not

To check if a node is present in a XML or not simply use boolean function

So for the XML


<person id="1"> <name>John Smith</name> <phone_home>12345</phone_home> <phone_office></phone_office> </person>





If we want to know if phone_home is present or not then simply say

boolean(/person/phone_office)

Similarly if you want to check if any phone is present or not

boolean(/person/*[contains(name(.),"phone")])

and in the same way it can be extended to more complex queries, like if any phone is empty

boolean(/person/*[contains(name(.),"phone") and .=""])

or if any or the nodes are empty:

boolean(/person/*[.=""])


Same approach can be applied based on node content.

So for XML


<jobs> <job seq="1">Job 1 Completed with status success</job> <job seq="2">Job 2 Completed with status success</job> <job seq="3">Job 3 Completed with status failure</job> <job seq="4">Job 4 Completed with status success</job> </jobs>







If we need to know if any of the jobs failed:

boolean(/jobs/job[contains(.,"status failure")])

Also, the same approach can be used based on attribute name

So for XML


<details> <detail name="John Smith"/> <detail phone_home="12345"/> <detail phone_office="54321"/> </details>






If we need to know if any of the attribute has phone in attribute name then:

boolean(/details/detail[contains(name(./@*), "phone")])

And same as with node names we can check if any of phone is empty:

boolean(/details/detail[contains(name(./@*), "phone") and ./@* = ""])

or if any of the attribute is empty

boolean(/details/detail[./@* = ""])

Hope this helps

Wednesday, 1 January 2014

Evaluate XPATH in Java

This is straight forward and I think better than iterating through the document tree. There is a evaluate method available in XPATH interface.

Here is a sample code for it:

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;


public class ApplyXPATH {

    public static void main(String[] args) {
        XPath xpath = XPathFactory.newInstance().newXPath();
        InputSource inputSource = new InputSource("XMLs/MultiNode.xml");
        String expression = "//node/data";
        NodeList outPut=null;
        try {
            outPut = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        for(int i=0; i<outPut.getLength();i++) {
            System.out.println(outPut.item(i).getFirstChild().getNodeValue());
        }
    }
}


Sample Input:
<root>
    <node>
        <data>123</data>
        <data>456</data>
        <junk>abc</junk>
    </node>
    <junknode>
        <junk>def</junk>
    </junknode>
    <node>
        <data>789</data>
        <junk>ghi</junk>
        <data>012</data>
    </node>
</root>


Sample Output:
123
456
789
012

Here I am just printing the node values but you can easily create a new XML document and append this nodelist to it.

PS: if you change the expression to //node/data/text() then to access the value you just need to do outPut.item(i).getNodeValue()