|
Nux 1.0a5 | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectnux.xom.xquery.XQuery
Compiled representation of a W3C XQuery (thread-safe).
Since XQuery is a superset of XPath 2.0 this class can also be used with
plain XPath expressions as queries. Also note that XPath 2.0 supports regular expressions via
the fn:matches
, fn:replace
, and fn:tokenize
functions.
Instances are considered immutable and thread-safe; The same compiled query may
be executed (evaluated) many times in series or in parallel,
just like XSLTransform
objects.
Requires saxon-8.1.1 or higher; Does not care whether it is an open-source or commercial Saxon version. To get started, simply add saxon8.jar to your classpath. Thanks to Michael Kay for that amazing piece of software! In case of problems, first check the saxon documentation and search the saxon mailing list as well as the XOM mailing list.
Example usage:
// find the links of all images in a XHTML-like document XQuery xquery = new XQuery("//*:img/@src", null); // find the links of all JPG images in a XHTML-like document via regular expression // XQuery xquery = new XQuery("//*:img/@src[matches(., '.jpg')]", null); Document doc = BuilderPool.GLOBAL_POOL.getBuilder(false).build(new File("/tmp/test.xml")); Nodes results = xquery.execute(doc).toNodes(); for (int i=0; i < results.size(); i++) { System.out.println("node "+i+": "+results.get(i).toXML()); //System.out.println("node "+i+": "+ XOMUtil.toPrettyXML(results.get(i))); }Here is another typical relational join XQuery that, for all bicycles, lists the item number, description, and highest bid (if any), ordered by item number:
for $i in doc("items.xml")//item_tuple let $b := doc("bids.xml")//bid_tuple[itemno = $i/itemno] where contains($i/description, "Bicycle") order by $i/itemno return <item_tuple> { $i/itemno } { $i/description } <high_bid>{ max($b/bid) }</high_bid> </item_tuple>Here is a query (using namespaces) that selects all records that have a remark in German:
declare namespace music = "http://www.example.org/music/records"; declare namespace xsd = "http://www.w3.org/2001/XMLSchema"; declare base-uri "http://example.org"; <Q5 xmlns:music="http://www.example.org/music/records"> { doc("tests/2003-11/usecases/ns/action.xml")//music:record[music:remark/@xml:lang = "de"] } </Q5>A query can declare external global variables, for example:
declare variable $foo as xs:string external (:: pragma saxon:default "hello" ::); declare variable $size as xs:integer external (:: pragma saxon:default 100 ::); declare variable $myuri as xs:anyURI external; declare variable $mynode as node() external; declare variable $myelem as element() external; declare variable $mynodes as node()* external;Such external global variable values can be passed to the query as follows:
Map vars = new HashMap(); vars.put("foo", "hello world"); vars.put("size", new Integer(99)); vars.put("myuri", "http://www.w3.org/2001/XMLSchema"); vars.put("mynode", new Document(new Element("xyz"))); vars.put("myelem", new Element("abc")); vars.put("mynodes", new ParentNode[] {new Document(new Element("elem1")), new Element("elem2"))}); xquery.execute(doc, null, vars);The Standard XQuery functions can be used directly. Custom extension functions written in Java can be defined and used as explained in the Saxon Extensibility Functions documentation.
Custom URI resolvers can be defined as explained in the
Saxon URI Resolver documentation.
These are made available to the query by calling setURIResolver()
on a DynamicQueryContext
(per execution),
or on the configuration object of a StaticQueryContext
(per query).
Performance note: For simple XPath expressions you can get a throughput of several thousand executions/sec for 10KB XHTML-like input documents, served from memory (commodity PC 2004, JDK 1.4.2). Be aware that this is an example ballpark figure at best, because use cases, documents and the complexity of queries vary wildly in practise.
Constructor Summary | |
XQuery(String query,
URI baseURI)
Constructs a new compiled XQuery from the given query. |
|
XQuery(String query,
URI baseURI,
StaticQueryContext staticContext,
DocumentURIResolver resolver)
Constructs a new compiled XQuery from the given query, base URI, static context and resolver. |
Method Summary | |
ResultSequence |
execute(ParentNode contextNode)
Executes (evaluates) the query against the given node (subtree). |
ResultSequence |
execute(ParentNode contextNode,
DynamicQueryContext dynamicContext,
Map variables)
Executes (evaluates) the query against the given node (subtree), using the given dynamic context and external variables. |
protected ResultSequence |
newResultSequence(XQueryExpression expression,
DynamicQueryContext dynamicContext)
Callback that returns a result sequence for the current query execution. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
public XQuery(String query, URI baseURI) throws XQueryException
query
- the query to compilebaseURI
- the base URI of the query. Used for resolving any relative
URI's found in the query, and used by the XQuery
doc
function. (May be null
in which case it defaults to the current working directory).
XQueryException
- if the syntax of the query is wrong, or if it references
namespaces, variables, or functions that have not been
declared, or contains other static errors.public XQuery(String query, URI baseURI, StaticQueryContext staticContext, DocumentURIResolver resolver) throws XQueryException
query
- the query to compilebaseURI
- the base URI of the query. Used for resolving any relative
URI's found in the query, and used by the XQuery
doc()
function, and hence the resolver. May be
null
in which case it defaults to the current
working directory.staticContext
- the context and configuration to use; per query (may be null
).resolver
- an object that is called by the XQuery processor to turn a URI
passed to the XQuery doc()
function into a XOM
Document
. May be null
in which case
Saxon's default resolution is used.
XQueryException
- if the syntax of the query is wrong, or if it references
namespaces, variables, or functions that have not been
declared, or contains other static errors.Method Detail |
public ResultSequence execute(ParentNode contextNode) throws XQueryException
contextNode
- the context node to execute the query against. The context
node is available to the query as the value of the query
expression ".". If this parameter is null
, the
context node will be undefined.
XQueryException
- if an error occurs during executionpublic ResultSequence execute(ParentNode contextNode, DynamicQueryContext dynamicContext, Map variables) throws XQueryException
Argument variables
specifies external global variables in the form of zero or more
variableName --> variableValue
map associations.
Each map entry's key and value are interpreted as follows:
ParentNode
object or a
ParentNode
[] array.
It follows the same conversion rules as a value returned
from a Saxon extension function. An error will occur at query
execution time if the supplied value cannot be converted to the required
type as declared in the query. For precise control of the type of the
value, instantiate one of the classes in the net.sf.saxon.value
package,
for example DateTimeValue
.
contextNode
- the context node to execute the query against. The context
node is available to the query as the value of the query
expression ".". If this parameter is null
, the
context node will be undefined.dynamicContext
- optional dynamic context of this execution (may be
null
).
If not null
, the Configuration object of the
dynamic context must be be the same as the Configuration
object that was used when creating the StaticQueryContext.variables
- optional external global variables on the dynamic context;
per execution (may be null
).
XQueryException
- if an error occurs during executionprotected ResultSequence newResultSequence(XQueryExpression expression, DynamicQueryContext dynamicContext) throws XQueryException
An XQuery result sequence may, apart from "normal" nodes, also contain top-level values of atomic types such as Long, Float, Boolean, etc, all of which are not XML nodes.
This method's result sequence implementation converts each top-level
atomic value to an Element
named "atomic" with a child
Text
node holding the value's string representation.
"Normal" nodes and anything not at top-level is returned "as is", without conversion.
Overrride this default implementation if you need custom conversions in result sequence implementations. Note however, that conversions of atomic values should rarely be used. It is often more desirable to avoid such atomic conversions altogether. This can almost always easily be achieved by formulating the xquery string such that it wraps atomic values via standard XQuery constructors (rather than via Java methods) into an element or attribute or document. That way, the query always produces a "normal" XML node sequence as output, and never produces a sequence of atomic values as output, and thus custom conversion by this class are never needed and invoked.
For example, by default the following query
for $i in (1, 2, 3) return $iyields this (perhaps somewhat unexpected) output:
<atomic type="java.lang.Long">1</atomic> <atomic type="java.lang.Long">2</atomic> <atomic type="java.lang.Long">3</atomic>
Hence, most likely you will want to rewrite the query along the following lines:
for $i in (1, 2, 3) return <item> {$i} </item>now yielding as output:
<item>1</item> <item>2</item> <item>3</item>Observe that the rewritten query converts top-level atomic values precisely as desired by the user, without needing any Java-level conversion.
expression
- the compiled query expressiondynamicContext
- the dynamic context of this execution
XQueryException
- if an error occurs during execution
|
Nux 1.0a5 | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |