| <html><head><META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Schema Aware</title><link href="book.css" type="text/css" rel="stylesheet"><link href="book.css" type="text/css" rel="stylesheet"><meta content="DocBook XSL Stylesheets V1.76.1" name="generator"><link rel="home" href="index.html" title="usermanual"><link rel="up" href="ch02.html" title="How to feed Psychopath XPath expressions"><link rel="prev" href="ch02.html" title="How to feed Psychopath XPath expressions"><link rel="next" href="ch02s03.html" title="How to use the XPath 2.0 grammar with PsychoPath"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="section" title="Schema Aware"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="Schema_Aware"></a>Schema Aware</h2></div></div></div><div class="literallayout"><p>/**<br> |
| * First load and optionally validate the XML document <br> |
| */<br> |
| // Create an InputStream from the XML document<br> |
| InputStream is = new FileInputStream("XPexample.xml");<br> |
| </p></div><div class="literallayout"><p>SchemaFactory schemaFactory = new XMLSchemaFactory();<br> |
| URL schemaURL = new File("XPexample.xsd").toURL();<br> |
| Schema jaxpschema = schemaFactory.newSchema(schemaURL);<br> |
| </p></div><div class="literallayout"><p>// Initializing the Xerces DOM loader.<br> |
| DOMLoader loader = new XercesLoader(jaxpschema);<br> |
| loader.set_validating(true);<br> |
| </p></div><div class="literallayout"><p>// Optionally set flag to validate XML document<br> |
| // loader.set_validating(validate);<br> |
| // Loads the XML document and stores the DOM root<br> |
| Document doc = loader.load(is);<br> |
| </p></div><div class="literallayout"><p>// Initialising the StaticContext using a builder with suitable defaults.<br> |
| StaticContextBuilder scb = new StaticContextBuilder();<br> |
| scb.withNamespace("xs", "http://www.w3.org/2001/XMLSchema");<br> |
| scb.withTypeModel(new XercesTypeModel(doc));<br> |
| </p></div><div class="literallayout"><p>/**<br> |
| * Parsing the XPath 2.0 expression into an executable expression, including<br> |
| * a static check and verification.<br> |
| */<br> |
| String xpathText = "for $elem in //*[. instance of xs:normalizedString] return concat(local-name($elem), ' : ', $elem/text())";<br> |
| XPath2Expression expr = new Engine().parseExpression(xpathText, scb);<br> |
| </p></div><div class="literallayout"><p>// Evaluates the XPath 2.0 expression, storing the result<br> |
| // in the ResultSequence<br> |
| ResultSequence rs = expr.evaluate(new DynamicContextBuilder(scb),<br> |
| new Object[] { doc });<br> |
| </p></div><div class="literallayout"><p>for (int i = 0; i < rs.size(); ++i) {<br> |
| System.out.println("#" + i + ": " + rs.value(i));<br> |
| }<br> |
| </p></div><p>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”). </p><p>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: </p><p>// Will return the number of elements in the sequence, in this </p><div class="literallayout"><p>// case of ’Hello World!’ expression size = 1. <br> |
| </p></div><div class="literallayout"><p>rs.size();<br> |
| </p></div><div class="literallayout"><p>// Will return the n’th element in the sequence, in this case of <br> |
| // ’Hello World!’, if n = 0, then it will return<br> |
| // “Hello World!”.<br> |
| </p></div><div class="literallayout"><p>rs.value(n);<br> |
| </p></div><div class="literallayout"><p>//Will return true if the sequence is empty.<br> |
| rs.empty(); <br> |
| </p></div><div class="literallayout"><p>// Will return the first element of the sequence, <br> |
| // in this example it will return xs:string of “Hello World!” <br> |
| rs.firstValue() <br> |
| </p></div><p> |
| |
| 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. </p><p>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: |
| </p><div class="literallayout"><p>String string = (String)(rs.value(0));<br> |
| <br> |
| </p></div><p>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 |
| </p><div class="literallayout"><p>ItemType itype = rs.itemType(n);<br> |
| Which will return the type of the n'th item in the result sequence.<br> |
| </p></div><p> |
| </p></div></body></html> |