Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "PsychoPathXPathProcessor/UserManual"

(Example)
(Indenting)
 
(44 intermediate revisions by 3 users not shown)
Line 7: Line 7:
 
== Getting PsychoPath ==
 
== Getting PsychoPath ==
  
Currently there is no standalone build of PsychoPath.  However, you can download the [http://download.eclipse.org/webtools/downloads/drops/R3.1/R-3.1-20090616035105/ WTP WST 3.1] zip file, and use the org.eclipse.wst.xml.xpath2.processor.jar file.  This jar has no dependencies on eclipse, and will work as a standard jar file.  If you are using an OSGI container, then this is treated as a standard OSGI bundle.
+
Standalone jars are only available through nightly builds.  However, you can download the current WTP builds, and use the org.eclipse.wst.xml.xpath2.processor.jar file.  This jar has no dependencies on eclipse, and will work as a standard jar file.  If you are using an OSGI container, then this is treated as a standard OSGI bundle.
 +
 
 +
{{tip | PsychoPath Nightly | If you want a standalone jar with only the processor framework, PsychoPath 2.0 is also available to [https://hudson.eclipse.org/hudson/view/WTP/job/cbi-wtp-wst.xsl.psychopath/ws/sourceediting/plugins/org.eclipse.wst.xml.xpath2.processor/target/] as a standalone jar.  Get the SDK zip file. PsychoPath 2.0 passes 99.9% of the XPath 2.0 test suite and is XML Schema Aware.}}
  
 
Additional dependencies you currently need are:
 
Additional dependencies you currently need are:
  
* Apache Commons Lang.
+
* IBM ICU 3.8
* IBM ICU
+
* Xerces 2.8.0 or greater
* Xerces 2.8.0
+
 
* JavaCup 0.10 or greater.
 
* JavaCup 0.10 or greater.
  
If using eclipse, these are all available from the Orbit project.   Others can find the necessary jars from their respective project pages.
+
These are all available from the [http://download.eclipse.org/tools/orbit/downloads/ Orbit project.]
  
 
= How to feed Psychopath XPath expressions  =
 
= How to feed Psychopath XPath expressions  =
Line 36: Line 37:
 
<source lang="java">
 
<source lang="java">
 
  /**
 
  /**
  * First load and optionally validate the XML document  
+
* First load and optionally validate the XML document  
 
  */
 
  */
 
   
 
   
 
  // Create an InputStream from the XML document
 
  // Create an InputStream from the XML document
  InputStream is = new FileInputStream(“XPexample.xml”);
+
  InputStream is = new FileInputStream("XPexample.xml");
 
   
 
   
 
  // Initializing the Xerces DOM loader.
 
  // Initializing the Xerces DOM loader.
 
  DOMLoader loader = new XercesLoader();
 
  DOMLoader loader = new XercesLoader();
 
   
 
   
  // Optionally set flag to validate XML document loader.setvalidating(validate);
+
  // Optionally set flag to validate XML document
 +
// loader.set_validating(validate);
 
  // Loads the XML document and stores the DOM root
 
  // Loads the XML document and stores the DOM root
 
  Document doc = loader.load(is);
 
  Document doc = loader.load(is);
 
   
 
   
/**
+
  // Initialising the StaticContext using a builder with suitable defaults.
  * Dynamic contexts must be initialised to defaults
+
  StaticContextBuilder scb = new StaticContextBuilder();
  * dependent on the XML Schema.
+
*/
+
+
// Extracting the schema from DOM root of Xpexpression.xml.
+
ElementPSVI rootPSVI = (ElementPSVI)doc.getDocumentElement();
+
XSModel schema = rootPSVI.getSchemaInformation();
+
+
  // Initialising the DynamicContext.
+
  DynamicContext dc = new DefaultDynamicContext(schema, doc);
+
+
// Register the namespaces of the XPath 2.0 predefined datatypes
+
dc.addnamespace(“xs”,”[http://www.w3.org/2001/XMLSchema http://www.w3.org/2001/XMLSchema]”);
+
+
// Register the XPath 2.0 standard functions
+
dc.addfunctionlibrary(new FnFunctionLibrary());
+
dc.addfunctionlibrary(new XSCtrLibrary());
+
 
   
 
   
 
  /**
 
  /**
   * Parsing the XPath 2.0 expression into an AST representation
+
   * Parsing the XPath 2.0 expression into an executable expression, including
*/
+
   * a static check and verification.
// Initialises PsychoPath’s supplied parser.
+
   */
XPathParser xpp = new JflexCupParser();
+
  String xpathText = "string-join(//character/name, ', ')";
+
  XPath2Expression expr = new Engine().parseExpression(xpathText, scb);
// Parses the XPath expression.
+
XPath xp = xpp.parse(xpath);
+
+
/**
+
   * Static check the AST to verift structural validity of 
+
   * XPath 2.0 expression
+
*/
+
   
+
// Initilising StaticChecker.
+
StaticChecker namecheck = new StaticNameResolver(sc);
+
+
// Static Checking the Xpath expression ’Hello World!’ namecheck.check(xp);
+
  /**
+
  * Evaluate the XPath 2.0 expression
+
*/
+
+
// Initialising the evaluator with DynamicContext and the name
+
// of the XML document XPexample.xml as parameters.
+
Evaluator eval = new DefaultEvaluator(dc, doc);  
+
 
   
 
   
 
  // Evaluates the XPath 2.0 expression, storing the result
 
  // Evaluates the XPath 2.0 expression, storing the result
 
  // in the ResultSequence
 
  // in the ResultSequence
  ResultSequence rs = eval.evaluate(xp);  
+
  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));
 +
}
 
</source>
 
</source>
 
<br>
 
<br>
Line 105: Line 77:
 
  /**
 
  /**
 
   * First load and optionally validate the XML document  
 
   * First load and optionally validate the XML document  
*/
+
  */
 
+
  SchemaFactory schemaFactory = new XMLSchemaFactory();
+
  URL schemaURL = new File("XPexample.xsd").toURL();
+
  Schema jaxpschema = schemaFactory.newSchema(schemaURL);
+
 
+
 
  // Create an InputStream from the XML document
 
  // Create an InputStream from the XML document
  InputStream is = new FileInputStream(“XPexample.xml”);
+
  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.
 
  // Initializing the Xerces DOM loader.
 
  DOMLoader loader = new XercesLoader(jaxpschema);
 
  DOMLoader loader = new XercesLoader(jaxpschema);
 +
loader.set_validating(true);
 
   
 
   
  // Optionally set flag to validate XML document loader.setvalidating(validate);
+
  // Optionally set flag to validate XML document
 +
// loader.set_validating(validate);
 
  // Loads the XML document and stores the DOM root
 
  // Loads the XML document and stores the DOM root
 
  Document doc = loader.load(is);
 
  Document doc = loader.load(is);
 
   
 
   
/**
+
  // Initialising the StaticContext using a builder with suitable defaults.
  * Dynamic contexts must be initialised to defaults
+
  StaticContextBuilder scb = new StaticContextBuilder();
  * dependent on the XML Schema.
+
  scb.withNamespace("xs", "http://www.w3.org/2001/XMLSchema");
*/
+
  scb.withTypeModel(new XercesTypeModel(doc));
+
// Extracting the schema from DOM root of Xpexpression.xml.
+
ElementPSVI rootPSVI = (ElementPSVI)doc.getDocumentElement();
+
XSModel schema = rootPSVI.getSchemaInformation();
+
+
  // Initialising the DynamicContext.
+
  DynamicContext dc = new DefaultDynamicContext(schema, doc);
+
   
+
// Register the namespaces of the XPath 2.0 predefined datatypes
+
dc.addnamespace(“xs”,”[http://www.w3.org/2001/XMLSchema http://www.w3.org/2001/XMLSchema]”);
+
   
+
// Register the XPath 2.0 standard functions
+
dc.addfunctionlibrary(new FnFunctionLibrary());
+
dc.addfunctionlibrary(new XSCtrLibrary());
+
 
   
 
   
 
  /**
 
  /**
   * Parsing the XPath 2.0 expression into an AST representation
+
   * Parsing the XPath 2.0 expression into an executable expression, including
*/
+
   * a static check and verification.
// Initialises PsychoPath’s supplied parser.
+
   */
XPathParser xpp = new JflexCupParser();
+
  String xpathText = "for $elem in //*[. instance of xs:normalizedString] return concat(local-name($elem), ' : ', $elem/text())";
+
  XPath2Expression expr = new Engine().parseExpression(xpathText, scb);
// Parses the XPath expression.
+
XPath xp = xpp.parse(xpath);
+
+
/**
+
   * Static check the AST to verift structural validity of 
+
   * XPath 2.0 expression
+
*/
+
   
+
// Initilising StaticChecker.
+
StaticChecker namecheck = new StaticNameResolver(sc);
+
+
// Static Checking the Xpath expression ’Hello World!’ namecheck.check(xp);
+
  /**
+
  * Evaluate the XPath 2.0 expression
+
*/
+
+
// Initialising the evaluator with DynamicContext and the name
+
// of the XML document XPexample.xml as parameters.
+
Evaluator eval = new DefaultEvaluator(dc, doc);  
+
 
   
 
   
 
  // Evaluates the XPath 2.0 expression, storing the result
 
  // Evaluates the XPath 2.0 expression, storing the result
 
  // in the ResultSequence
 
  // in the ResultSequence
  ResultSequence rs = eval.evaluate(xp);  
+
  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));
 +
}
 
</source>
 
</source>
  
Line 176: Line 121:
  
 
<source lang="java">// Will return the number of elements in the sequence, in this  
 
<source lang="java">// Will return the number of elements in the sequence, in this  
// case of ’Hello World!’ expression size = 1. rs.size();
+
// case of ’Hello World!’ expression size = 1.  
// Will return the n’th element in the sequence, in this case of  
+
 
// ’Hello World!’, if n = 1, then it will return
+
rs.size();
// XSString of “Hello World!”, but if n = 2, it will return
+
 
// Empty Result.
+
// 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.get(n);
+
  rs.value(n);
  
 
  //Will return true if the sequence is empty.
 
  //Will return true if the sequence is empty.
Line 188: Line 135:
  
 
  // Will return the first element of the sequence,  
 
  // Will return the first element of the sequence,  
  // in this example it will return XSString of “Hello World!”  
+
  // in this example it will return xs:string of “Hello World!”  
  rs.first()  
+
  rs.firstValue()  
 
</source>  
 
</source>  
<br> However, all the items extracted will be of the type’s base class AnyType and need to be casted into its actual subtype.  
+
<br> 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:  
 
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:  
<source lang="java">XSString xsstring = (XSString)(rs.first());</source>
+
<source lang="java">
The actual result can now be extracted from this XSString in the following manner:
+
String string = (String)(rs.value(0));
<source lang="java">String str = xsstring.value();</source>  
+
</source>  
The details of how to cast extracted items from AnyType into their actual subtypes with examples is in the next section on How to use each production in the grammar.  
+
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
 
+
<source lang="java">
However, if the expected return type is unknown or multiple types are possible, the types hierarchy can be traversed in a breadth first manner making use of the Java instanceof operator to ascertain the actual type.&nbsp;
+
ItemType itype = rs.itemType(n);</source>
 +
Which will return the type of the n'th item in the result sequence.
  
 
<br>
 
<br>
Line 210: Line 158:
  
 
String literals are written as “Hello” or ‘Hello’. In each case the opposite kind of quotation mark can be used within the string: ‘He said “Hello” ’ or “London is a big city”. To feed PsychoPath, “ ‘Hello World!’ ”or “ “Hello World!” ” can be used to feed it with strings. Remember that the ResultSequence returns AnyType so since a string is being expected as the result, first it has to be casted in the code like this:  
 
String literals are written as “Hello” or ‘Hello’. In each case the opposite kind of quotation mark can be used within the string: ‘He said “Hello” ’ or “London is a big city”. To feed PsychoPath, “ ‘Hello World!’ ”or “ “Hello World!” ” can be used to feed it with strings. Remember that the ResultSequence returns AnyType so since a string is being expected as the result, first it has to be casted in the code like this:  
<source lang="java">XSString xsstring = (XSString)(rs.first());</source>  
+
<source lang="java">String xsstring = (String)(rs.firstValue());</source>  
Numeric constants follow the Java rules for decimal literals: for example, 4 or 4.67; a negative number can be written as -3.05. The numeric literal is taken as a double precision floating point number if it uses scientific notation (e.g. 1.0e7), as a fixed point decimal if it includes a decimal point, or as an integer otherwise. When extracting number literals from the ResultSequence, possible types to be returned include ''XSDecima''l (e.g.&nbsp;: xs:decimal: 4.67),''XSInteger ''(e.g.&nbsp;: xs:integer: 4) or ''XSDouble'' (e.g.&nbsp;: xs:double 1e0). All of which need to be casted in the same manner as stated before: from AnyType to their corresponding types.  
+
Numeric constants follow the Java rules for decimal literals: for example, 4 or 4.67; a negative number can be written as -3.05. The numeric literal is taken as a double precision floating point number if it uses scientific notation (e.g. 1.0e7), as a fixed point decimal if it includes a decimal point, or as an integer otherwise. When extracting number literals from the ResultSequence, possible types to be returned include ''BigDecima''l (e.g.&nbsp;: xs:decimal: 4.67),''Int ''(e.g.&nbsp;: xs:integer: 4) or ''XSDouble'' (e.g.&nbsp;: xs:double 1e0). All of which need to be casted in the same manner as stated before: from AnyType to their corresponding types.  
  
 
There are no boolean constants as such: ''true, false'' instead the function calls '''true()''' and '''false()''' are used.  
 
There are no boolean constants as such: ''true, false'' instead the function calls '''true()''' and '''false()''' are used.  
Line 243: Line 191:
  
 
The expression E1 except E2 selects all nodes that are in E1 unless they are also in E2. Both expressions must return sequences of nodes. The results are returned in document order. For example, @* except @note returns all attributes except the note attribute. The expression E1 intersect E2 selects all nodes that are in both E1 and E2. Both expressions must return sequences of nodes. The results are returned in document order. The expression E1 union E2 selects all nodes that are in either E1 or E2 or both. Both expressions must return sequences of nodes. The results are returned in document order. A complete example of the above expression would be as follows. Consider an XML document which looks like this:  
 
The expression E1 except E2 selects all nodes that are in E1 unless they are also in E2. Both expressions must return sequences of nodes. The results are returned in document order. For example, @* except @note returns all attributes except the note attribute. The expression E1 intersect E2 selects all nodes that are in both E1 and E2. Both expressions must return sequences of nodes. The results are returned in document order. The expression E1 union E2 selects all nodes that are in either E1 or E2 or both. Both expressions must return sequences of nodes. The results are returned in document order. A complete example of the above expression would be as follows. Consider an XML document which looks like this:  
<source lang="xml">
+
<source lang="xml">
<nodes>
+
<nodes>
 
   <a>
 
   <a>
 
     <connecteda>A</connecteda>
 
     <connecteda>A</connecteda>
Line 255: Line 203:
 
     <connectedb>D</connectedb>
 
     <connectedb>D</connectedb>
 
   </b>
 
   </b>
</nodes>
+
</nodes>
 
</source>  
 
</source>  
 
then an example of each of the expressions would be:  
 
then an example of each of the expressions would be:  
Line 356: Line 304:
 
The operators '''is''' and '''isnot''' test whether the operands represent the same (identical) node. For example, ''title[1] is *[@note][1]'' is true if the first title child is the first child element that has a ''@note'' attribute. If either operand is an empty sequence the result is an empty sequence (which will usually be treated as false).  
 
The operators '''is''' and '''isnot''' test whether the operands represent the same (identical) node. For example, ''title[1] is *[@note][1]'' is true if the first title child is the first child element that has a ''@note'' attribute. If either operand is an empty sequence the result is an empty sequence (which will usually be treated as false).  
  
The operators '''&lt;&lt;''' and '''&gt;&gt;''' test whether one node precedes or follows another in document order. Consider this XML document:  
+
The operators '''&lt;&lt;''' and '''&gt;&gt;''' test whether one node precedes or follows another in document order. Consider this XML document (XPexample.xml):  
<source lang="xml"><book>
+
<source lang="xml">
 +
<book>
 
   <title>Being a Dog Is a Full-Time Job</title>
 
   <title>Being a Dog Is a Full-Time Job</title>
 
   <author>Charles M. Schulz</author>
 
   <author>Charles M. Schulz</author>
Line 373: Line 322:
 
     <qualification>bold, brash and tomboyish</qualification>
 
     <qualification>bold, brash and tomboyish</qualification>
 
   </character>
 
   </character>
</book>
+
</book>
 +
</source>
 +
 
 +
This file conforms to the following Schema (XPexample.xsd):
 +
 
 +
<source lang="xml"><?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 +
  elementFormDefault="qualified">
 +
 +
  <xs:element name="book">
 +
    <xs:complexType>
 +
      <xs:sequence>
 +
        <xs:element ref="title" />
 +
        <xs:element ref="author" />
 +
        <xs:element maxOccurs="unbounded" ref="character" />
 +
      </xs:sequence>
 +
    </xs:complexType>
 +
  </xs:element>
 +
 
 +
  <xs:element name="title" type="characterName"></xs:element>
 +
 +
  <xs:element name="author" type="characterName"></xs:element>
 +
 +
  <xs:element name="character">
 +
    <xs:complexType>
 +
      <xs:sequence>
 +
        <xs:element ref="name" />
 +
        <xs:element ref="friend-of" minOccurs="0" />
 +
        <xs:element ref="since" />
 +
        <xs:element ref="age" />
 +
        <xs:element ref="qualification" />
 +
      </xs:sequence>
 +
    </xs:complexType>
 +
  </xs:element>
 +
  <xs:element name="name" type="characterName" />
 +
  <xs:element name="friend-of" type="characterName" />
 +
  <xs:element name="since" type="xs:date" />
 +
  <xs:element name="age" type="xs:nonNegativeInteger" />
 +
  <xs:element name="qualification" type="xs:string" />
 +
 +
  <xs:simpleType name="characterName">
 +
    <xs:restriction base="xs:normalizedString">
 +
      <xs:minLength value="1"/>
 +
    </xs:restriction>
 +
  </xs:simpleType>
 +
</xs:schema>
 
</source>  
 
</source>  
  
Line 487: Line 481:
  
 
In order for PsychoPath to operate on instances of the XPath 2.0 data model, the model must expose the properties of the items it contains. It does this by defining a family of accessor functions. These functions are not available to users or applications to call directly. Instead, they are descriptions of the information that an implementation of the model must expose to applications.  
 
In order for PsychoPath to operate on instances of the XPath 2.0 data model, the model must expose the properties of the items it contains. It does this by defining a family of accessor functions. These functions are not available to users or applications to call directly. Instead, they are descriptions of the information that an implementation of the model must expose to applications.  
 
=== Example  ===
 
  
 
<pre>data(‘string’)</pre>
 
<pre>data(‘string’)</pre>
Line 497: Line 489:
  
 
in order to get the result of ‘string’
 
in order to get the result of ‘string’
 
== The Error and Trace Functions  ==
 
  
 
== Constructor Functions  ==
 
== Constructor Functions  ==
 
=== Example  ===
 
  
 
<pre>xs:dateTime("2002-02-01T10:00:00+06:00")</pre>
 
<pre>xs:dateTime("2002-02-01T10:00:00+06:00")</pre>
Line 513: Line 501:
  
 
== Functions on Numeric Values  ==
 
== Functions on Numeric Values  ==
 
=== Example  ===
 
  
 
<pre>ceiling(xs:float(‘10.4’))</pre>
 
<pre>ceiling(xs:float(‘10.4’))</pre>
Line 524: Line 510:
 
in order to get the result of ‘11.0’  
 
in order to get the result of ‘11.0’  
  
<br>
 
  
 
== Functions to Assemble and Disassemble Strings  ==
 
== Functions to Assemble and Disassemble Strings  ==
  
=== Example  ===
 
  
 
<pre>codepoints-to-string(0111)</pre>
 
<pre>codepoints-to-string(0111)</pre>
Line 539: Line 523:
  
 
== Compare and Other Functions on String Values  ==
 
== Compare and Other Functions on String Values  ==
 
=== Example  ===
 
  
 
<pre>concat(‘un’, ‘grateful’)</pre>
 
<pre>concat(‘un’, ‘grateful’)</pre>
Line 546: Line 528:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>String n = ((XSString)rs.first()).stringvalue(); println(n);</pre>
+
<source lang="java">String n = ((XSString)rs.first()).stringvalue(); println(n);</source>
  
 
in order to get the result of ‘ungrateful’
 
in order to get the result of ‘ungrateful’
Line 552: Line 534:
 
== Functions Based on Substring Matching  ==
 
== Functions Based on Substring Matching  ==
  
=== Example  ===
 
  
 
<pre>contains("abc", "edf")</pre>
 
<pre>contains("abc", "edf")</pre>
Line 558: Line 539:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>boolean n = ((XSBoolean)rs.first()).value(); println(n);</pre>
+
<source lang="java">boolean n = ((XSBoolean)rs.first()).value(); println(n);</source>
  
 
in order to get the result of ‘false’
 
in order to get the result of ‘false’
Line 564: Line 545:
 
== String Functions that Use Pattern Matching  ==
 
== String Functions that Use Pattern Matching  ==
  
=== Example  ===
 
  
 
<pre>matches(‘abcd’, ‘abcd’)</pre>
 
<pre>matches(‘abcd’, ‘abcd’)</pre>
Line 570: Line 550:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>boolean n = ((XSBoolean)rs.first()).value(); println(n);</pre>
+
<source lang="java">boolean n = ((XSBoolean)rs.first()).value(); println(n);</source>
  
 
in order to get the result of ‘true’
 
in order to get the result of ‘true’
Line 576: Line 556:
 
== Functions on Boolean Values  ==
 
== Functions on Boolean Values  ==
  
=== Example  ===
 
  
 
<pre>not(true())</pre>
 
<pre>not(true())</pre>
Line 582: Line 561:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>
+
<source lang="java">
 
boolean n = ((XSBoolean)rs.first()).value();
 
boolean n = ((XSBoolean)rs.first()).value();
 
println(n);
 
println(n);
</pre>
+
</source>
  
 
in order to get the result of ‘false’
 
in order to get the result of ‘false’
Line 591: Line 570:
 
== Component Extraction Functions on Durations, Dates and Times  ==
 
== Component Extraction Functions on Durations, Dates and Times  ==
  
=== Example  ===
 
  
 
<pre>timezone-from-time(xs:time("13:20:00+05:00"))</pre>
 
<pre>timezone-from-time(xs:time("13:20:00+05:00"))</pre>
Line 597: Line 575:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>String n = ((XDTDayTimeDuration)rs.first()).stringvalue(); println(n);</pre>
+
<source lang="java">String n = ((XDTDayTimeDuration)rs.first()).stringvalue(); println(n);</source>
  
 
in order to get the result of ‘PT5H’
 
in order to get the result of ‘PT5H’
Line 603: Line 581:
 
== Functions Related to QNames  ==
 
== Functions Related to QNames  ==
  
=== Example  ===
 
  
 
<pre>local-name-from-QName(QName(‘http://www.example.com/example’, ‘person’))</pre>
 
<pre>local-name-from-QName(QName(‘http://www.example.com/example’, ‘person’))</pre>
Line 609: Line 586:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>String n = ((XSNCName)rs.first()).stringvalue(); println(n); </pre>
+
<source lang="java">String n = ((XSNCName)rs.first()).stringvalue(); println(n); </source>
  
 
in order to get the result of ‘person’
 
in order to get the result of ‘person’
  
 
== Functions on Nodes  ==
 
== Functions on Nodes  ==
 +
  
 
=== General Functions on Sequences  ===
 
=== General Functions on Sequences  ===
 
==== Example  ====
 
  
 
<pre>remove((‘s’,‘o’,‘m’,‘e’,‘t’,‘h’,‘i’,‘n’,‘g’), 6)</pre>
 
<pre>remove((‘s’,‘o’,‘m’,‘e’,‘t’,‘h’,‘i’,‘n’,‘g’), 6)</pre>
Line 635: Line 611:
  
 
=== Functions That Test the Cardinality of Sequences  ===
 
=== Functions That Test the Cardinality of Sequences  ===
 
==== Example  ====
 
  
 
<pre>one-or-more((1,2,3,4,5))</pre>
 
<pre>one-or-more((1,2,3,4,5))</pre>
Line 642: Line 616:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>
+
<source lang="java">
 
for (Iterator iter = rs.iterator(); iter.hasNext();) {
 
for (Iterator iter = rs.iterator(); iter.hasNext();) {
 
   Object item = iter.next();
 
   Object item = iter.next();
Line 649: Line 623:
 
}
 
}
 
println("");  
 
println("");  
</pre>
+
</source>
  
 
in order to get the result of ‘1 2 3 4 5’
 
in order to get the result of ‘1 2 3 4 5’
Line 655: Line 629:
 
=== Deep-Equal, Aggregate Functions, and Functions that Generate Sequences  ===
 
=== Deep-Equal, Aggregate Functions, and Functions that Generate Sequences  ===
  
==== Example  ====
 
  
 
<pre>avg((3,4,5))</pre>  
 
<pre>avg((3,4,5))</pre>  
Line 661: Line 634:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>double avg = ((XSDouble)rs.first()).doublevalue(); println(avg);</pre>  
+
<source lang="java">double avg = ((XSDouble)rs.first()).doublevalue(); println(avg);</source>  
  
 
in order to get the result of ‘4.0’
 
in order to get the result of ‘4.0’
Line 667: Line 640:
 
=== Context Functions  ===
 
=== Context Functions  ===
  
==== Example  ====
 
  
 
<pre>(10 to 20)[position() = 2]</pre>
 
<pre>(10 to 20)[position() = 2]</pre>
Line 673: Line 645:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>int pos = ((XSInteger)rs.first()).intvalue(); println(pos);</pre>
+
<source lang="java">int pos = ((XSInteger)rs.first()).intvalue(); println(pos);</source>
  
 
in order to get the result of ‘11’
 
in order to get the result of ‘11’
Line 685: Line 657:
 
== Operators on Numeric Values  ==
 
== Operators on Numeric Values  ==
  
=== Example  ===
 
  
 
<pre>xs:integer(4) + xs:integer(3)</pre>
 
<pre>xs:integer(4) + xs:integer(3)</pre>
Line 697: Line 668:
 
== Comparison of Numeric Values  ==
 
== Comparison of Numeric Values  ==
  
=== Example  ===
 
  
 
<pre>xs:decimal(3.3) = xs:decimal(6.6)</pre>
 
<pre>xs:decimal(3.3) = xs:decimal(6.6)</pre>
Line 703: Line 673:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>boolean n = ((XSBoolean)rs.first()).value(); println(n);</pre>
+
<source lang="java">boolean n = ((XSBoolean)rs.first()).value(); println(n);</source>
  
 
in order to get the result of ‘false’
 
in order to get the result of ‘false’
Line 709: Line 679:
 
== Operators on Boolean Values  ==
 
== Operators on Boolean Values  ==
  
=== Example  ===
 
  
 
<pre>xs:boolean(’true’) gt xs:boolean(’false’)</pre>
 
<pre>xs:boolean(’true’) gt xs:boolean(’false’)</pre>
Line 720: Line 689:
  
 
== Comparisons of Duration, Date and Time Values  ==
 
== Comparisons of Duration, Date and Time Values  ==
 
=== Example  ===
 
  
 
<pre>xs:time("23:00:00+06:00") lt xs:time("12:00:00-06:00")</pre>
 
<pre>xs:time("23:00:00+06:00") lt xs:time("12:00:00-06:00")</pre>
Line 727: Line 694:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>boolean n = ((XSBoolean)rs.first()).value(); println(n);</pre>
+
<source lang="java">boolean n = ((XSBoolean)rs.first()).value(); println(n);</source>
  
 
in order to get the result of ‘true’
 
in order to get the result of ‘true’
  
 
== Arithmetic Functions on Durations  ==
 
== Arithmetic Functions on Durations  ==
 
=== Example  ===
 
  
 
<pre>multiply-dayTimeDuration(xdt:dayTimeDuration("PT2H10M"), 2.1)</pre>  
 
<pre>multiply-dayTimeDuration(xdt:dayTimeDuration("PT2H10M"), 2.1)</pre>  
Line 739: Line 704:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>String n = ((XDTDayTimeDuration)rs.first()).stringvalue(); println(n);</pre>
+
<source lang="java">String n = ((XDTDayTimeDuration)rs.first()).stringvalue(); println(n);</source>
  
 
which returns a xdt:dayTimeDuration value corresponding to 4 hours and 33 minutes ‘PT4H33M’
 
which returns a xdt:dayTimeDuration value corresponding to 4 hours and 33 minutes ‘PT4H33M’
  
 
== Arithmetic Functions Dates and Times  ==
 
== Arithmetic Functions Dates and Times  ==
 
=== Example  ===
 
  
 
<pre>add-yearMonthDuration-to-dateTime( xs:dateTime("2000-10-30T11:12:00"), xdt:yearMonthDuration("P1Y2M"))</pre>  
 
<pre>add-yearMonthDuration-to-dateTime( xs:dateTime("2000-10-30T11:12:00"), xdt:yearMonthDuration("P1Y2M"))</pre>  
Line 751: Line 714:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>String n = ((XSDateTime)rs.first()).stringvalue(); println(n);</pre>
+
<source lang="java">String n = ((XSDateTime)rs.first()).stringvalue(); println(n);</source>
  
 
which returns an xs:dateTime value corresponding to the lexical representation ‘2001-12-30T11:12:00’
 
which returns an xs:dateTime value corresponding to the lexical representation ‘2001-12-30T11:12:00’
Line 757: Line 720:
 
== Operators Related to QNames And Nodes  ==
 
== Operators Related to QNames And Nodes  ==
  
=== Example  ===
 
  
 
<pre>xs:QName(’ao’) eq xs:QName(’ao’)</pre>
 
<pre>xs:QName(’ao’) eq xs:QName(’ao’)</pre>
Line 763: Line 725:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>boolean n = ((XSBoolean)rs.first()).value(); println(n);</pre>
+
<source lang="java">boolean n = ((XSBoolean)rs.first()).value(); println(n);</source>
  
 
which returns the result of ‘true’
 
which returns the result of ‘true’
Line 769: Line 731:
 
== Union, Intersection and Except  ==
 
== Union, Intersection and Except  ==
  
=== Example  ===
 
  
 
<pre>union($seq2, $seq3)</pre>
 
<pre>union($seq2, $seq3)</pre>
Line 789: Line 750:
  
 
== Operators that Generate Sequences  ==
 
== Operators that Generate Sequences  ==
 
=== Example  ===
 
  
 
<pre>(1 to 3)</pre>
 
<pre>(1 to 3)</pre>
Line 796: Line 755:
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
 
from within a Java application, in order to extract the result from the result sequence, one would have to use this code:  
  
<pre>int n = (XSInteger)rs.first()).stringvalue(); println(n);</pre>
+
<source lang="java">int n = (XSInteger)rs.first()).stringvalue(); println(n);</source>
  
 
which returns the sequence consisting of 1, 2, 3.  
 
which returns the sequence consisting of 1, 2, 3.  
  
 
----
 
----
 +
 +
[[Category:Draft_Documentation]]

Latest revision as of 21:53, 18 May 2011

Contents

Introduction

What is PsychohPath? PsychoPath is a XPath 2.0 XML Schema Aware processor. It is nearly fully compliant to the XPath 2.0 test suite. It is a library that does not require eclipse to be used. Known adopters of PsychoPath include the Xerces-J project for XML Schemas 1.1 assertion support.

PsychoPath is the only known open-source java XPath 2.0 processor that is fully schema aware. SAXON HE only supports the core functionality. XML Schema awarness provides tighter static checking, and can be used to help determine if certain operations can or should occur on an XML node. For a detailed description of the PsychoPath's design please see the design document.

Getting PsychoPath

Standalone jars are only available through nightly builds. However, you can download the current WTP builds, and use the org.eclipse.wst.xml.xpath2.processor.jar file. This jar has no dependencies on eclipse, and will work as a standard jar file. If you are using an OSGI container, then this is treated as a standard OSGI bundle.

Idea.png
PsychoPath Nightly
If you want a standalone jar with only the processor framework, PsychoPath 2.0 is also available to [1] as a standalone jar. Get the SDK zip file. PsychoPath 2.0 passes 99.9% of the XPath 2.0 test suite and is XML Schema Aware.


Additional dependencies you currently need are:

  • IBM ICU 3.8
  • Xerces 2.8.0 or greater
  • JavaCup 0.10 or greater.

These are all available from the Orbit project.

How to feed Psychopath XPath expressions

Since PsychoPath has been implemented as an external library and not as a complete program, in order to use it, it needs to be accessed from inside another program. To process XPath 2.0 expressions using PsychoPath from another programs one needs to go through the following process:

  1. Load the XML document
  2. Optionally validate the XML document
  3. Initialize static and dynamic context in respect to the document root
  4. Parse the XPath 2.0 expression
  5. Statically verify the XPath 2.0 expression
  6. Evaluate the XPath 2.0 expression in respect to the XML document

To give a better idea of how this process actually works, we’ll go through an example of processing and evaluating the string expression “Hello World!”. In this example the XML document that we load is called “XPexample.xml”.

All 5 main steps have been explained in detail in User Interface, so below is just a brief code summary:

Non-Schema Aware

 /**
 * First load and optionally validate the XML document 
 */
 
 // Create an InputStream from the XML document
 InputStream is = new FileInputStream("XPexample.xml");
 
 // Initializing the Xerces DOM loader.
 DOMLoader loader = new XercesLoader();
 
 // 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();
 
 /**
  * Parsing the XPath 2.0 expression into an executable expression, including
  * a static check and verification.
  */
 String xpathText = "string-join(//character/name, ', ')";
 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));
 }


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.


How to use the XPath 2.0 grammar with PsychoPath

In this section we will try to give you an overview of the XPath 2.0 grammar in general and how each production in the grammar should be used with PsychoPath. For the formal specifications, see the W3C web-site for XPath 2.0 specification http://www.w3.org/TR/xpath20.

Constants

String literals are written as “Hello” or ‘Hello’. In each case the opposite kind of quotation mark can be used within the string: ‘He said “Hello” ’ or “London is a big city”. To feed PsychoPath, “ ‘Hello World!’ ”or “ “Hello World!” ” can be used to feed it with strings. Remember that the ResultSequence returns AnyType so since a string is being expected as the result, first it has to be casted in the code like this:

String xsstring = (String)(rs.firstValue());

Numeric constants follow the Java rules for decimal literals: for example, 4 or 4.67; a negative number can be written as -3.05. The numeric literal is taken as a double precision floating point number if it uses scientific notation (e.g. 1.0e7), as a fixed point decimal if it includes a decimal point, or as an integer otherwise. When extracting number literals from the ResultSequence, possible types to be returned include BigDecimal (e.g. : xs:decimal: 4.67),Int (e.g. : xs:integer: 4) or XSDouble (e.g. : xs:double 1e0). All of which need to be casted in the same manner as stated before: from AnyType to their corresponding types.

There are no boolean constants as such: true, false instead the function calls true() and false() are used.

Constants of other data types can be written using constructors. These look like function calls but require a string literal as their argument. For example, xs:float(“10.7”) produces a single-precision floating point number.

Path expressions

A path expression is a sequence of steps separated by the / or // operator. For example, ../@desc selects the desc attribute of the parent of the context node.

In XPath 2.0, path expressions have been generalized so that any expression can be used as an operand of /, (both on the left and the right), as long as its value is a sequence of nodes. For example, it is possible to use a union expression (in parentheses) or a call to the id() function.

In practice, it only makes sense to use expressions on the right of "/" if they depend on the context item. It is legal to write $x/$y provided both $x and $y are sequences of nodes, but the result is exactly the same as writing ./$y.

Note that the expressions ./$X or $X/. can be used to remove duplicates from $X and sort the results into document order.

The operator // is an abbreviation for /descendant-or-self::node(). An expression of the form /E is shorthand for root(.)/E, and the expression / on its own is shorthand for root(.).

Axis steps

The basic primitive for accessing a source document is the axis step. Axis steps may be combined into path expressions using the path operators "/" and "//", and they may be filtered using filter expressions in the same way as the result of any other expression.

An axis step has the basic form axis::node-test, and selects nodes on a given axis that satisfy the node-test. The axes available are:

  1. element: age
  2. element: age

The rest of the axes act in the same manner.

Set difference, intersection and Union

The expression E1 except E2 selects all nodes that are in E1 unless they are also in E2. Both expressions must return sequences of nodes. The results are returned in document order. For example, @* except @note returns all attributes except the note attribute. The expression E1 intersect E2 selects all nodes that are in both E1 and E2. Both expressions must return sequences of nodes. The results are returned in document order. The expression E1 union E2 selects all nodes that are in either E1 or E2 or both. Both expressions must return sequences of nodes. The results are returned in document order. A complete example of the above expression would be as follows. Consider an XML document which looks like this:

 <nodes>
   <a>
     <connecteda>A</connecteda>
     <connecteda>B</connecteda>
     <connecteda>C</connecteda>
   </a>
   <b>
     <connectedb>B</connectedb>
     <connectedb>C</connectedb>
     <connectedb>D</connectedb>
   </b>
 </nodes>

then an example of each of the expressions would be:

data(/a/*) union data(/b/*)

result:

  1. xs:string: A
  2. xs:string: B
  3. xs:string: C
  4. xs:string: D
data(/a/*) intersect data(/b/*)

result:

  1. xs:string: B
  2. xs:string: C
data(/a/*) except data(/b/*)

result:

  1. xs:string: D

Arithmetic Expressions

Unary

minus and plus: The unary minus operator changes the sign of a number. For example -1 is minus one, and -1e0 is the double value negative -1.

Multiplication and Division:

The operator * multiplies two numbers. If the operands are of different types, XPath 2.0 specifications say that one of them is promoted to the type of the other.  The result is the same type as the operands after promotion.


The operator div divides two numbers. Dividing two integers produces a double; in other cases the result is the same type as the operands.


The operator idiv performs integer division. For example, the result of 10 idiv 3 is 3.


The mod operator returns the modulus (or remainder) after division.


The operators * and div may also be used to multiply or divide a range by a number.

For example, (1 idiv 1 to 3) returns the result: xs:integer: 1, xs:integer: 2, xs:integer: 3

Addition and Subtraction:

The operators + and - perform addition and subtraction of numbers, in the usual way. Once again, if the operands are of different types, XPath 2.0 specifications say one of them is promoted but numeric type promotion is currently unsupported by PsychoPath. The result is of the same type as the operands.

Examples of above would be:

-(5 + 7)

result:

  1. xs:integer: -12
-xs:float(’1.23’)

result:

  1. xs:float: -1.23
-xs:double(’1.23’)

result:

  1. xs:double: -1.23
(+5 - +7)

result:

  1. xs:integer: -2
(1 to 5 div 0 )

result:

  • FAIL (division by zero!)
5*6*10*5*96 div 20 div 3 div 1

result:

  1. xs:decimal: 2400.0
31 mod 15

result:

  1. xs:integer: 1

Range expressions

The expression E1 to E2 returns a sequence of integers. For example, 1 to 5 returns the sequence 1, 2, 3, 4, 5. This is useful in for expressions, for example the first five nodes of a node sequence can be processed by writing for $i in 1 to 5 return (//x)[$i]. Another example:

(1+1 to 10)

result:

  1. xs:integer: 2
  2. xs:integer: 3
  3. xs:integer: 4
  4. xs:integer: 5
  5. xs:integer: 6
  6. xs:integer: 7
  7. xs:integer: 8
  8. xs:integer: 9
  9. xs:integer: 10

Comparisons

The simplest comparison operators are eq, ne, lt, le, gt, ge. These compare two atomic values of the same type, for example two integers, two dates, or two strings. (Collation hasn’t been implemented in current version of PsychoPath). If the operands are not atomic values, an error is raised.

The operators =!=, <=, >, <, and >= can compare arbitrary sequences. The result is true if any pair of items from the two sequences has the specified relationship, for example $A = $B is true if there is an item in $A that is equal to some item in $B.

The operators is and isnot test whether the operands represent the same (identical) node. For example, title[1] is *[@note][1] is true if the first title child is the first child element that has a @note attribute. If either operand is an empty sequence the result is an empty sequence (which will usually be treated as false).

The operators << and >> test whether one node precedes or follows another in document order. Consider this XML document (XPexample.xml):

 <book>
  <title>Being a Dog Is a Full-Time Job</title>
  <author>Charles M. Schulz</author>
  <character>
    <name>Snoopy</name>
    <friend-of>Peppermint Patty</friend-of>
    <since>1950-10-04</since>
    <age>2</age>
    <qualification>extroverted beagle</qualification>
  </character>
  <character>
    <name>Peppermint Patty</name>
    <since>1966-08-22>/since>
    <age>4</age>
    <qualification>bold, brash and tomboyish</qualification>
  </character>
 </book>

This file conforms to the following Schema (XPexample.xsd):

<?xml version="1.0" encoding="UTF-8"?>
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified">
 
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="title" />
        <xs:element ref="author" />
        <xs:element maxOccurs="unbounded" ref="character" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
 
  <xs:element name="title" type="characterName"></xs:element>
 
  <xs:element name="author" type="characterName"></xs:element>
 
  <xs:element name="character">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="name" />
        <xs:element ref="friend-of" minOccurs="0" />
        <xs:element ref="since" />
        <xs:element ref="age" />
        <xs:element ref="qualification" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="name" type="characterName" />
  <xs:element name="friend-of" type="characterName" />
  <xs:element name="since" type="xs:date" />
  <xs:element name="age" type="xs:nonNegativeInteger" />
  <xs:element name="qualification" type="xs:string" />
 
  <xs:simpleType name="characterName">
    <xs:restriction base="xs:normalizedString">
      <xs:minLength value="1"/>
    </xs:restriction>
  </xs:simpleType>
 </xs:schema>

Examples:

book/character[name="Snoopy"] << book/character[name="Peppermint Patty"] 

result:

  1. xs:boolean: true
book/character[name="Peppermint Patty"] << book/character[name="Snoopy"]

result:

  1. xs:boolean: false

Conditional Expressions

XPath 2.0 allows a conditional expression of the form if ( E1 ) then E2 else E3. For example, if (@discount) then @discount else 0 returns the value of the discount attribute if it is present, or zero otherwise.


Quantified Expressions

The expression some $x in E1 satisfies E2 returns true if there is an item in the sequence E1 for which the effective boolean value of E2 is true. Note that E2 must use the range variable $x to refer to the item being tested; it does not become the context item. For example, some $x in @* satisfies $x eq "" is true if the context item is an element that has at least one zero-length attribute value.

Similarly, the expression every $x in E1 satisfies E2 returns true if every item in the sequence given by E1 satisfies the condition.

And, Or Expressions

The expression E1 and E2 returns true if the effective boolean values of E1 and E2 are both true. The expression E1 or E2 returns true if the effective boolean values of either or both of E1 and E2 are true.

Example: (for a truth table)

1 and 1

result:

  1. xs:boolean: true


1 and 0

result:

  1. xs:boolean: false


1 or 0

result:

  1. xs:boolean: true


0 or 1

result:

  1. xs:boolean: true


SequenceType Matching Expressions

The rules for SequenceType matching compare the actual type of a value with an expected type. These rules are a subset of the formal rules that match a value with an expected type defined in XQuery 1.0 and XPath 2.0 Formal Semantics http://www.w3.org/TR/xpath20/#XQueryFormalSemantics, because the Formal Semantics must be able to match a value with any XML Schema type, whereas the rules below only match values against those types expressible by the SequenceType syntax.

Some of the rules for SequenceType matching require determining whether a given type name is the same as or derived from an expected type name. The given type name may be "known" (defined in the in-scope schema definitions), or "unknown" (not defined in the in-scope schema definitions). An unknown type name might be encountered, for example, if a source document has been validated using a schema that was not imported into the static context. In this case, an implementation is allowed (but is not required) to provide an implementation-dependent mechanism for determining whether the unknown type name is derived from the expected type name. For example, an implementation might maintain a data dictionary containing information about type hierarchies. consider the following XML document:

<sorbo>
  <is>elite</is>
  <!-- life sux -->
</sorbo>

then, the following are some example of SequenceType matchings:

element({*})

result:

  1. element: sorbo


element(elite)

result:

  1. Empty results
 sorbo/comment()

result:

  1. comment: life sux
 data(/sorbo/comment())

result:

  1. xs:string: life sux


sorbo/node()

result:

  1. text:
  2. element: is
  3. comment: life sux
  4. text:


How to use XPath 2.0 functions with PsychoPath

The aim of this section is to give the user an overview of the available XPath 2.0 functions that are implemented in PsychoPath. For the formal specifications, see the W3C web-site for XPath 2.0 functions and operators http://www.w3.org/TR/xpath-functions/.

Accessors

In order for PsychoPath to operate on instances of the XPath 2.0 data model, the model must expose the properties of the items it contains. It does this by defining a family of accessor functions. These functions are not available to users or applications to call directly. Instead, they are descriptions of the information that an implementation of the model must expose to applications.

data(‘string’)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

String n = ((XSString)rs.first()).stringvalue(); println(n);

in order to get the result of ‘string’

Constructor Functions

xs:dateTime("2002-02-01T10:00:00+06:00")

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

String n = ((XSDateTime)rs.first()).stringvalue(); println(n);

in order to get the result of ‘2002-02-01T04:00:00Z’

Functions on Numeric Values

ceiling(xs:float(‘10.4’))

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

float n = ((XSFloat)rs.first()).floatvalue(); println(n);

in order to get the result of ‘11.0’


Functions to Assemble and Disassemble Strings

codepoints-to-string(0111)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

String n = ((XSString)rs.first()).stringvalue(); println(n);

in order to get the result of ‘o’

Compare and Other Functions on String Values

concat(‘un’, ‘grateful’)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

String n = ((XSString)rs.first()).stringvalue(); println(n);

in order to get the result of ‘ungrateful’

Functions Based on Substring Matching

contains("abc", "edf")

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

boolean n = ((XSBoolean)rs.first()).value(); println(n);

in order to get the result of ‘false’

String Functions that Use Pattern Matching

matches(‘abcd’, ‘abcd’)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

boolean n = ((XSBoolean)rs.first()).value(); println(n);

in order to get the result of ‘true’

Functions on Boolean Values

not(true())

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

boolean n = ((XSBoolean)rs.first()).value();
println(n);

in order to get the result of ‘false’

Component Extraction Functions on Durations, Dates and Times

timezone-from-time(xs:time("13:20:00+05:00"))

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

String n = ((XDTDayTimeDuration)rs.first()).stringvalue(); println(n);

in order to get the result of ‘PT5H’

Functions Related to QNames

local-name-from-QName(QName(‘http://www.example.com/example’, ‘person’))

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

String n = ((XSNCName)rs.first()).stringvalue(); println(n);

in order to get the result of ‘person’

Functions on Nodes

General Functions on Sequences

remove((‘s’,‘o’,‘m’,‘e’,‘t’,‘h’,‘i’,‘n’,‘g’), 6)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

for (Iterator iter = rs.iterator(); iter.hasNext();) {
   Object item = iter.next(); 
   String n = ((XSString)item).stringvalue();
   print(n + " ");
}
println("");

in order to get the result of ‘s o m e t i n g’

Functions That Test the Cardinality of Sequences

one-or-more((1,2,3,4,5))

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

for (Iterator iter = rs.iterator(); iter.hasNext();) {
  Object item = iter.next();
  int n = ((XSInteger)item).intvalue();
  print(n + " ");
}
println("");

in order to get the result of ‘1 2 3 4 5’

Deep-Equal, Aggregate Functions, and Functions that Generate Sequences

avg((3,4,5))

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

double avg = ((XSDouble)rs.first()).doublevalue(); println(avg);

in order to get the result of ‘4.0’

Context Functions

(10 to 20)[position() = 2]

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

int pos = ((XSInteger)rs.first()).intvalue(); println(pos);

in order to get the result of ‘11’

How to use XPath 2.0 operators with PsychoPath

The aim of this section is to give the user an overview of the available XPath 2.0 operators that are implemented in PsychoPath. For the formal specifications, see the W3C web-site for XPath 2.0 functions and operators http://www.w3.org/TR/xpath-functions/.


Operators on Numeric Values

xs:integer(4) + xs:integer(3)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

Integer n = ((XSInteger)rs.first()).integervalue(); println(n);

in order to get the result of ‘7’

Comparison of Numeric Values

xs:decimal(3.3) = xs:decimal(6.6)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

boolean n = ((XSBoolean)rs.first()).value(); println(n);

in order to get the result of ‘false’

Operators on Boolean Values

xs:boolean(’true’) gt xs:boolean(’false’)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

boolean n = ((XSBoolean)rs.first()).value(); println(n);

in order to get the result of ‘true’

Comparisons of Duration, Date and Time Values

xs:time("23:00:00+06:00") lt xs:time("12:00:00-06:00")

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

boolean n = ((XSBoolean)rs.first()).value(); println(n);

in order to get the result of ‘true’

Arithmetic Functions on Durations

multiply-dayTimeDuration(xdt:dayTimeDuration("PT2H10M"), 2.1)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

String n = ((XDTDayTimeDuration)rs.first()).stringvalue(); println(n);

which returns a xdt:dayTimeDuration value corresponding to 4 hours and 33 minutes ‘PT4H33M’

Arithmetic Functions Dates and Times

add-yearMonthDuration-to-dateTime( xs:dateTime("2000-10-30T11:12:00"), xdt:yearMonthDuration("P1Y2M"))

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

String n = ((XSDateTime)rs.first()).stringvalue(); println(n);

which returns an xs:dateTime value corresponding to the lexical representation ‘2001-12-30T11:12:00’

Operators Related to QNames And Nodes

xs:QName(’ao’) eq xs:QName(’ao’)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

boolean n = ((XSBoolean)rs.first()).value(); println(n);

which returns the result of ‘true’

Union, Intersection and Except

union($seq2, $seq3)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

for (Iterator iter = rs.iterator(); iter.hasNext();) {
 Object item = iter.next();
 String n = ((XSString)item).stringvalue();
 print(n + ", ");
}
println("");

which returns the sequence consisting of $item1, $item2, $item3.


Operators that Generate Sequences

(1 to 3)

from within a Java application, in order to extract the result from the result sequence, one would have to use this code:

int n = (XSInteger)rs.first()).stringvalue(); println(n);

which returns the sequence consisting of 1, 2, 3.


Back to the top