XQuery engine from Altova
, offers XSLT engines and this XQuery engine free for developers. I downloaded the
, a free XML editor (and more?) to see if it will be useful for the emXML project.
XQuery seems to duplicate and
extend the basic functions of XSL. I wonder if it is actually more
suitable for transforming emXML data, for example, to a standard
format, or to plain ASCII data tables. One advantage of XQuery –
considered a drawback by this article,
from which the following example is drawn — is that it is much more
human readable like a programming language. Indeed it is a programming
language, rather than an XML file.
Example 17. (Q9) List the titles of books published by Morgan Kaufmann in 1998.
FOR $b IN document("bib.xml")//bookWHERE $b/publisher = "Morgan Kaufmann"AND $b/year = "1998"RETURN $b/title
Example 18. XSLT equivalent to (Q9)
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:for-each select="document(’bib.xml’)//book"> <xsl:if test="publisher=’Morgan Kaufmann’ and year=’1998′"> <xsl:copy-of select="title"/> </xsl:if> </xsl:for-each> </xsl:template></xsl:transform>
The Altova XQuery Engine is an XQuery processor that is fully compatible with the W3C XQuery 1.0
specification. It is packaged as a Windows executable with command-line
control and is suitable for use in both client- and server-side
application development. Use the exact same XQuery processor that is
available in our award-winning XMLSpy development environment in your
solutions!
The Altova XQuery Engine is available for Windows 2000/XP/2003 (Unicode-compatible) operating systems.
To
download the Altova XQuery Engine, please click on the link below. The
Altova XQuery Engine is contained in a ZIP-compressed file:
| Altova XQuery Engine 2005 Altova XQuery Engine 2005 online help file |
The
Altova XQuery Engine is available for you to use both for your own
purposes and to integrate into your solutions without paying any
royalties or license fees. Please read the respective Altova XSLT/XQuery Engine developer license agreement for more information.
Syntax: A quick sampler
Let’s take a quick look at a few XQuery features in the light of an
actual example. Here’s a very simple query that operates on one of the
canonical sample files in the Use Cases document. This query
illustrates XQuery’s ability to both project (select a subset of nodes in the dataset matching desired criteria) and transform
(produce an output document that differs from the one being queried
against). XQuery allows you to both specify what you’re looking for and
designate what its output format should look like in the same query.
Here’s a fragment of the document on which this query is operating:
|
Here’s what we want the resulting output document (somewhat prettified) to look like:
|
And here’s the query itself. Its job is to scan through all the books
in the queried document, generating the result document shown above
that: contains a computed authorCount attribute in each new
<book> tag being output; and discards most of the remaining
information from the original, retaining only each author’s last name.
(Note that I’m using the term "queried document" (singular) here.
That’s a simplification. XQuery’s data model is capable of handling
collections as well.)
|
Also note that the query itself doesn’t specify the document or dataset
context against which it’s being evaluated. That’s determined by the
particular query engine being used.
Here are a few interesting features of this query:
The example contains two nested for loops and a let. The outer for
iterates through each of the nodes resulting from the expansion of the
path expression, //book, isolating each <book> node in turn in a
variable named $book. The let expression in turn picks up all the
<author> subnodes of each book in a variable named $authors. The
$authors variable holds a node sequence; both the variables $book and $author hold single nodes.
It’s important to note that these variables aren’t assigned to, they’re bound.
The distinction is subtle but important: Once a variable’s been bound,
its value is immutable. This prevents nasty side effects that can
result from reassigning the value of a variable on the fly. Another
potential benefit is that lines containing variables can (to some
degree) be rearranged during processing, allowing savvy engines to
optimize their queries.
The for and let expressions are subcomponents of a FLWOR (pronounced flower) expression. The formal grammar for a FLWOR expression:
|
shows that it’s quite a protean expression type, capable of generating
a large number of possible query instances. As this production shows,
the Expr term following the "return" keyword can itself be replaced by
another FLWOR expression, so that FLWOR’s can be strung together on end
ad infinitum,
like an ever-lengthening sequence of LEGO blocks. The replacement of an
Expr term by any other expression type is what makes XQuery composable
and gives it its rich, expressive power. There are a large number of
expression types in XQuery, each capable of being plugged into the
grammar wherever a more generic Expr is called for.
On a more mundane note, eventually a return statement will terminate a
FLWOR sequence. And in the case of the query above, an additional
internal return is used as a convenient point to insert an element
constructor for each <book> that’s being output.
The query contains three element constructors. The elements
<results>, <book>, and <author> are generated on the
fly by writing the literal angle-bracket XML directly into the body of
the query itself.
Braces ({ and })
are used where necessary to disambiguate literal text content from
subexpressions inside an element constructor that require evaluation.
If we were emitting the literal expression
|
for example, we wouldn’t require braces to separate the inner tag from the outer.
Braces, by the way, were introduced in the June, 2001 revision of the
surface-language syntax. Earlier versions of the grammar didn’t require
them. Braces are a good example of how the language changes and evolves as
it moves toward Recommendation.
The line
|
shows the use of an inline attribute constructor. The count() function returns the number of <author>
elements contained in each book. Note again the braces, used here to
cordon off an expression requiring evaluation. The final version of the
specification may require computed attribute expression such as this to
be delimited by quotes; currently either alternative is allowable.
Built-in functions and operators
count()
is an example of a built-in function. The "Functions and Operators"
draft lists close to 250 functions and operators in 14 different groups
that construct and operate on a wide variety of datatypes, including
numbers, strings, booleans, dates and times, qnames, nodes, and
sequences.
The text() operator is used in the expression
|
to populate the contents of each <author> element with the
text of the last name pulled out of its enclosing <last> element.
If you just used $author/last directly, you’d get the enclosing tag as
well, something that’s not wanted in this case.