Schema Aware

/**
 * First load and optionally validate the XML document 
 */
// Create an InputStream from the XML document
InputStream is = new FileInputStream("XPexample.xml");

SchemaFactory schemaFactory = new XMLSchemaFactory();
URL schemaURL = new File("XPexample.xsd").toURL();
Schema jaxpschema = schemaFactory.newSchema(schemaURL);

// Initializing the Xerces DOM loader.
DOMLoader loader = new XercesLoader(jaxpschema);
loader.set_validating(true);

// Optionally set flag to validate XML document
// loader.set_validating(validate);
// Loads the XML document and stores the DOM root
Document doc = loader.load(is);

// Initialising the StaticContext using a builder with suitable defaults.
StaticContextBuilder scb = new StaticContextBuilder();
scb.withNamespace("xs", "http://www.w3.org/2001/XMLSchema");
scb.withTypeModel(new XercesTypeModel(doc));

/**
 * Parsing the XPath 2.0 expression into an executable expression, including
 * a static check and verification.
 */
String xpathText = "for $elem in //*[. instance of xs:normalizedString] return concat(local-name($elem), ' : ', $elem/text())";
XPath2Expression expr = new Engine().parseExpression(xpathText, scb);

// Evaluates the XPath 2.0 expression, storing the result
// in the ResultSequence
ResultSequence rs = expr.evaluate(new DynamicContextBuilder(scb),
new Object[] { doc });

for (int i = 0; i < rs.size(); ++i) {
System.out.println("#" + i + ": " + rs.value(i));
}

XPath 2.0 defines everything to be a sequence of items, including the arguments to expressions and the result of operations. Thus, the overall result of an XPath expression evaluation is also a sequence of items. PsychoPath uses the class ResultSequence as a Collections wrapper to store these sequences and therefore, the result of an evaluation is of this type also. The ResultSequence consists of zero or more items; an item may be a node or a simple-value. “Hello World!” is an example of a single value with length 1. A general sequence could be written as (“a”, “s”, “d”, “f”).

Extraction of certain items from the ResultSequence class is described below, with details of the different operations that one might apply on the ResultSequence. Consider that ’rs’ is the ResultSequence, then:

// Will return the number of elements in the sequence, in this

// case of ’Hello World!’ expression size = 1. 

rs.size();

// Will return the n’th element in the sequence, in this case of 
// ’Hello World!’, if n = 0, then it will return
// “Hello World!”.

rs.value(n);

//Will return true if the sequence is empty.
rs.empty(); 

// Will return the first element of the sequence, 
// in this example it will return xs:string of “Hello World!” 
rs.firstValue() 

However, all the items extracted will be of the type’s "native" value (statically known as Object) and need to be casted into its actual subtype.

Certain operations always return a particular type and using this knowledge, the extracted item can be immediately casted. In our example “Hello World!” returns a string (easily known as it is inside the quotes ’ ’ ), so this can safely be casted as such:

String string = (String)(rs.value(0));
 

The details of how to cast extracted items from Object into their actual subtypes with examples is in the next section on How to use each production in the grammar. As an alternative, you can call

ItemType itype = rs.itemType(n);
Which will return the type of the n'th item in the result sequence.