Next page Previous page Start of chapter End of chapter

XPath evaluation

JAXP supports XPath 1.0 query evaluation with package javax.xml.xpath. To evaluate a query, follow these steps:

  1. obtain an XPath factory:
    XPathFactory factory = XPathFactory.newInstance();
    
  2. obtain an XPath evaluator:
    XPath xpath = factory.newXPath();
    
  3. compile an XPath query:
    XPathExpression queryExpression = xpath.compile(query);
    
    where query is a string containing an XPath statement. You may skip this step and do the compilation at execution time. However, it is more efficient to compile a query once and then evaluate it several times;
  4. evaluate the compiled XPath query:
    queryExpression.evaluate(document, resultType);
    
    where document is either a Node object (for DOM representations) or an InputSource object (for SAX representations), and resultType is the result type of the query. The possible result types are the following:
    • XPathConstants.NODESET: the result is a node set and can be assigned to a NodeList object;
    • XPathConstants.STRING: the result is a string and can be assigned to a String object; this is the default and in this case the type parameter of the evaluate() method can be omitted;
    • XPathConstants.NUMBER: the result is a number and can be assigned to a Double object;
    • XPathConstants.BOOLEAN: the result is a boolean and can be assigned to a Boolean object.

The following XPathEval evaluates an XPath query against an XML document and serializes the answer in a well-formed XML document, which is printed on the standard output (the parsing of the document is associated to the error handler ValidHandler):

import java.io.*;
import javax.xml.xpath.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

public class XPathEval {
    
  static final String usage = 
    "Syntax: java XPathEval query -r (nodeset|string|number|boolean) document.xml";

  public static void main(String[] args) {

    if (args.length != 3) {
      System.out.println(usage);
      System.exit(1);
    }
  
    if (!(args[1].equals("nodeset") || args[1].equals("string") ||
          args[1].equals("number") || args[1].equals("boolean"))) {
      System.out.println(usage);
      System.exit(1);
    }
        
    String query = args[0];
    String resultType = args[1];
    String documentName = args[2];
    
    // get an XPath factory
    XPathFactory factory = XPathFactory.newInstance();
    
    // get an XPath evaluator
    XPath xpath = factory.newXPath();

    // compile the XPath query
    XPathExpression queryExpression = null;
    try {
      queryExpression = xpath.compile(query);
    } catch (XPathExpressionException xee) {
        // compilation failure
      System.err.println("Compilation failure: " + xee.getMessage());
      System.exit(1);
    }
      
    // parse the document  
    DocumentBuilder parser = null;
    try {
      parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    } catch (ParserConfigurationException pce) {
        // compilation failure
      System.err.println(pce.getMessage());
      System.exit(1);
    }
    // register an error handler with the parser
    parser.setErrorHandler(new ValidHandler());

    Document document = null;
    try {
      document = parser.parse(new File(documentName));
    } catch (SAXException se) {
       // do nothing since an error handler has been installed
    } catch (IOException ioe) {
      // Some IO error occurred
      System.err.println(ioe.getMessage());
      System.exit(1);
    } 
      
    // evaluate the query according to its result type
    Object result = null;    
    try {
      if (resultType.equals("nodeset")) {
        result = (NodeList) 
            queryExpression.evaluate(document, XPathConstants.NODESET);
      }
      
      if (resultType.equals("number")) {
        result = (Double) queryExpression.evaluate(document, XPathConstants.NUMBER);
      }
      
      if (resultType.equals("string")) {
        result = (String) queryExpression.evaluate(document, XPathConstants.STRING);
      }
    
      if (resultType.equals("boolean")) {
        result = (Boolean) queryExpression.evaluate(document, XPathConstants.BOOLEAN);
      }
    } catch (XPathExpressionException xee) {
      // evaluation failure
      System.err.println("Evaluation failure: " + xee.getMessage());
      System.exit(1);
    }
    
    // create an answer document
    Document answer = parser.newDocument();
    Element answerNode = answer.createElement("answer");
    if (resultType.equals("nodeset")) {
      NodeList answerNodeSet = (NodeList) result;
      int card = answerNodeSet.getLength();
      for(int i = 0; i < card; i++) {
        Node n = answerNodeSet.item(i);
        if (n.getNodeType() == Node.ATTRIBUTE_NODE) {
          Element attribute = answer.createElement("attribute");
          attribute.setAttribute(n.getNodeName(), n.getNodeValue());
          answerNode.appendChild(attribute);
        } else {
          answerNode.appendChild(answer.importNode(n, true));
        }
      }
    }
    if (resultType.equals("number")) {
      Double resultNumber = (Double) result;
      answerNode.appendChild(answer.createTextNode(resultNumber.toString()));
    }
    if (resultType.equals("string")) {
      String resultString = (String) result;
      answerNode.appendChild(answer.createTextNode(resultString));
    }
    if (resultType.equals("boolean")) {
      Boolean resultBoolean = (Boolean) result;
      answerNode.appendChild(answer.createTextNode(resultBoolean.toString()));
    }
    answer.appendChild(answerNode);
    
    Transformer transformer = null;
    try {
      transformer = TransformerFactory.newInstance().newTransformer();
    } catch (TransformerConfigurationException tce) {
      // the transformer cannot be created
      System.err.println(tce.getMessage());
      System.exit(1);
    }
    DOMSource input = new DOMSource(answer);
    StreamResult output = new StreamResult(System.out); 
    try {
      transformer.transform(input, output);
    } catch (TransformerException te) {
      // transformation failure
      System.err.println("Transformation failure: " + te.getMessage());
      System.exit(1);
    }
    
  }
}
Next page Previous page Start of chapter End of chapter
Caffè XML - Massimo Franceschet