Friday 7 February 2014

How can we use XPath in Java PART-2?



Sample example to work with XPath


In the previous post we learned about the XPath where I mentioned about XPath nodes, XPath Constant, XPath datatypes, XPath syntax, predicates & wildcard in XPath. Now we will see, how to use XPath expressions to extract specific data from XML source document.

XPath Operators List:-

Operator
Description
Example
|
Help to compute two nodes
//name|//java-experience
or
or
salary=50000 or salary=45000
and
and
Salary>40000 and salary<60000
mod
Division reminder(modules)
9 mod 2(Reminder 1)
+
Addition
10 + 5
-
Subtraction
10 – 5
*
Multiplication
10 * 5
div
Division
10 div 5
=
Equal
Salary = 50000
!=
Not equal
Salary != 50000
Less than
Salary < 50000
<=
Less than or equal to
Salary <= 50000
Greater than
Salary > 50000
>=
Greater than or equal to
Salary >= 50000

Many inbuilt functions are available in XPath, like Accessor, String, Numeric e.t.c. For more info visit
http://www.w3schools.com/xpath/xpath_functions.asp#string

A sample XML

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE note SYSTEM "employee.dtd">

<employees>

      <!--Test is a comment-->

      <employee id="1234">

            <name>KUMAR GAURAV</name>

            <designation>SYSTEM ENGINEER</designation>

            <java-experience>7</java-experience>

            <salary>50000</salary>

      </employee>

      <employee id="2341">

            <name>KUMAR AADITYA</name>

            <designation>PROGRAM MANAGER</designation>

            <java-experience>15</java-experience>

            <salary>70000</salary>

      </employee>

</employees>



XPathSample.java

package com.gaurav.xpath.demo;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathException;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * @author gaurav
 *   
 */
public class XPathSample {

      /**
       * This method will help to display the XML elements when we are using NODESET constant of XPath.
       *   
       */
      public static void displayXpathResult(Object result) {
            NodeList nodes = (NodeList) result;
            for (int i = 0; i < nodes.getLength(); i++) {
                  System.out.println(nodes.item(i).getNodeValue());
            }
      }

      /**
       * This method will help to display the XML elements when we are using NODESET constant of XPath and XPath wildcard.
       *   
       */
      public static void displayXpathWildCardResult(Object result) {
            NodeList nodeList = (NodeList) result;
            for (int i = 0; i < nodeList.getLength(); i++) {
                  if (nodeList.item(i).getFirstChild() != null) {
                        System.out.println(nodeList.item(i).getNodeName() + " : \t"
                                    + nodeList.item(i).getFirstChild().getNodeValue());

                  }
            }
      }
     
      /**
       * This method will help to display the XML elements when we are using NODE constant of XPath.
       *   
       */
      private static void displayXPathResultForNode(Node node) {
            NodeList nodeListData;
            if(null != node) {
                  nodeListData = node.getChildNodes();
                for (int i = 0;null!=nodeListData && i < nodeListData.getLength(); i++) {
                    Node nod = nodeListData.item(i);
                    if(nod.getNodeType() == Node.ELEMENT_NODE)
                        System.out.println(nodeListData.item(i).getNodeName() + " : " + nod.getFirstChild().getNodeValue());
                }
            }
      }
     
      public static void main(String[] args) throws XPathException,
                  ParserConfigurationException, SAXException, IOException {

           
            // DocumentBuilderFactory is created for reading xml file
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory
                        .newInstance();

           
            // We can use this below line if we want to skip dtd available in the XML file
            builderFactory
                        .setFeature(
                                    "http://apache.org/xml/features/nonvalidating/load-external-dtd",
                                    false);

            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse("src\\employees.xml");

           
           
            // Creation of XPathFactory which is required for creating XPath Object
            XPathFactory xPathFactory = XPathFactory.newInstance();

           
           
            // Creation of XPath object from XPathFactory
            XPath xpath = xPathFactory.newXPath();

           
           
            // Compiling the XPath expression for getting all employee names
            XPathExpression xPathExpr = xpath
                        .compile("/employees/employee/name/text()");

           
           
            // XPath example using NODESET CONSTANT.
            Object result = xPathExpr.evaluate(document, XPathConstants.NODESET);
            System.out
                        .println("***** All available employees are as follows : *****");
            displayXpathResult(result);
           
           
           
           
            // XPath example using NODE CONSTANT.
            System.out.println("\n***** All available employees are as follows using NODE CONSTANT : *****");
            Node node = (Node) xpath.compile("/employees/employee[@id='2341']").evaluate(document, XPathConstants.NODE);
            displayXPathResultForNode(node);         
           
           
           
           
            // get all employees salary using xpath expression in java
            NodeList nodeList = (NodeList) xpath.compile(
                        "/employees/employee/salary/text()").evaluate(document,
                        XPathConstants.NODESET);
            System.out
                        .println("\n***** All salaries for the available employees using NODESET CONSTANT : *****");
           
            for (int i = 0; i < nodeList.getLength(); i++) {

                  System.out.println(nodeList.item(i).getNodeName() + "\t"
                              + nodeList.item(i).getNodeValue());

            }
           
           
            // get only one(first) employee name using xpath expression in java
            String nodeList1 = (String) xpath.compile(
                        "/employees/employee/name/text()").evaluate(document,
                        XPathConstants.STRING);
            System.out
                        .println("\n***** Name of the first employee using STRING CONSTANT : *****");
            System.out.println(nodeList1);

           
           
            // XPath expression to use wildcard.
            Object wildCardResult = xpath.compile("/employees/employee/*")
                        .evaluate(document, XPathConstants.NODESET);
            System.out
                        .println("\n***** Displaying all element using wildcard in XPath expression : *****");
            displayXpathWildCardResult(wildCardResult);

           
           
            // XPath expression to count employee nodes in the XML source document.
            Double count = (Double) xpath.compile("count(/employees/employee)")
                        .evaluate(document, XPathConstants.NUMBER);
            System.out
                        .println("\n***** Use of Count with the help of NUMBER CONSTANT : *****");
            System.out.println("How many employees are available : " + count);

           
           
            // XPath conditional example
            Boolean flag = (Boolean) xpath.compile(
                        "count(/employees/employee[@id='2341']) > 0").evaluate(
                        document, XPathConstants.BOOLEAN);
            System.out
            .println("\n***** Use of Count with the help of BOOLEAN CONSTANT : *****");
            System.out
                        .println("Is any employee is available with the ID=1234 using BOOLEAN CONSTANT : "
                                    + flag);

      }
}



Result:-

***** All available employees are as follows : *****
KUMAR GAURAV
KUMAR AADITYA

***** All available employees are as follows using NODE CONSTANT : *****
name : KUMAR AADITYA
designation : PROGRAM MANAGER
java-experience : 15
salary : 70000

***** All salaries for the available employees using NODESET CONSTANT : *****
#text 50000
#text 70000

***** Name of the first employee using STRING CONSTANT : *****
KUMAR GAURAV

***** Displaying all element using wildcard in XPath expression : *****
name :      KUMAR GAURAV
designation :     SYSTEM ENGINEER
java-experience :       7
salary :    50000
name :      KUMAR AADITYA
designation :     PROGRAM MANAGER
java-experience :       15
salary :    70000

***** Use of Count with the help of NUMBER CONSTANT : *****
How many employees are available : 2.0

***** Use of Count with the help of BOOLEAN CONSTANT : *****
Is any employee is available with the ID=1234 using BOOLEAN CONSTANT : true