lunedì 14 maggio 2012

Java XPATH example with namespace

http://www.xinotes.org/notes/note/795/

This is a Java program to test XPATH expressions with namespace option. It's been tested with JDK1.6.

import java.io.FileInputStream;
import java.util.Iterator;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.xpath.*;
import javax.xml.namespace.NamespaceContext;

import org.w3c.dom.*;

public class XPathExample {
    public static void main(String[] args) throws Exception {
 if (args.length < 2) {
     usage();
     return;
 }

 String inputFile = args[0];
 String xPathStr = args[1];

 // optional namespace spec: xmlns:prefix:URI
 String nsPrefix = null;
 String nsUri = null;
 if ((args.length >= 3) && args[2].startsWith("xmlns:")) {
     String[] nsDef = args[2].substring("xmlns:".length()).split("=");
     if (nsDef.length == 2) {
  nsPrefix = nsDef[0];
  nsUri = nsDef[1];
     }
 }
 
 // Parse XML to DOM
 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
 dbFactory.setNamespaceAware(true);
 Document doc = dbFactory
         .newDocumentBuilder()
         .parse(new FileInputStream(inputFile));

 // Find nodes by XPATH
 XPathFactory xpFactory = XPathFactory.newInstance();
 XPath xpath = xpFactory.newXPath();

 // namespace?
 if (nsPrefix != null) {
     final String myPrefix = nsPrefix;
     final String myUri = nsUri;
     xpath.setNamespaceContext(new NamespaceContext() {
  public String getNamespaceURI(String prefix) {
      return myPrefix.equals(prefix) ?  myUri : null;
  }

  public String getPrefix(String namespaceURI) {
      return null; // we are not using this.
  }

  public Iterator getPrefixes(String namespaceURI) {
      return null; // we are not using this.
  }
     });
 }

 XPathExpression expr = xpath.compile(xPathStr);
 NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
 if (nodes.getLength() < 1) {
     System.out.println("Can't find node by XPATH: " + xPathStr);
 }
 else {
     System.out.println(nodes.getLength() 
        + " nodes found for " 
        + xPathStr);
 }
    }

    private static void usage() {
 System.out.println("Usage: java XPathExample <inputFile> <XPathExpr> [namespaceDef]");
    }
}


Following Getting Started with XML Security, these are the test files:

  • Without namespace (patient.xml).
    <PatientRecord>    
        <Name>John Doe</Name>    
        <Account id="acct">123456</Account>    
        <Visit date="10pm March 10, 2002">    
     <Diagnosis>Broken second metacarpal</Diagnosis>    
     <Diagnosis>    
         <Xray>xhzhez</Xray>    
     </Diagnosis>
        </Visit>    
    </PatientRecord>
    
  • With namespace (patient_ns.xml).
    <med:PatientRecord xmlns:med="http://www.medical.org/">    
        <Name>John Doe</Name>    
        <Account id="acct">123456</Account>    
        <Visit date="10pm March 10, 2002">    
     <Diagnosis>Broken second metacarpal</Diagnosis>    
     <Diagnosis>    
         <Xray>xhzhez</Xray>    
     </Diagnosis>
        </Visit>    
    </med:PatientRecord>
    


Test results:

C:\>java XPathExample patient.xml /PatientRecord/Visit/Diagnosis
2 nodes found for /PatientRecord/Visit/Diagnosis

C:\>java XPathExample patient_ns.xml /PatientRecord/Visit/Diagnosis
Can't find node by XPATH: /PatientRecord/Visit/Diagnosis

C:\>java XPathExample patient_ns.xml /PatientRecord/Visit/Diagnosis xmlns:med="http://www.medical.org"
Can't find node by XPATH: /PatientRecord/Visit/Diagnosis

C:\>java XPathExample patient_ns.xml /med:PatientRecord/Visit/Diagnosis xmlns:med="http://www.medical.org"
Can't find node by XPATH: /med:PatientRecord/Visit/Diagnosis

C:\>java XPathExample patient_ns.xml /med:PatientRecord/Visit/Diagnosis xmlns:med="http://www.medical.org/"
2 nodes found for /med:PatientRecord/Visit/Diagnosis

C:\>java XPathExample patient.xml /med:PatientRecord/Visit/Diagnosis xmlns:med="http://www.medical.org/"
Can't find node by XPATH: /med:PatientRecord/Visit/Diagnosis

Nessun commento: