The best way to explain XQuery is to say that XQuery is to XML what SQL is to database tables. [...] XQuery is built on XPath expressions. XQuery 1.0 and XPath 2.0 share the same data model and support the same functions and operators.
from w3schools.com
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
Let us look at a sorting example. Using code like this:
for $x in doc("books.xml")/bookstore/book
where $x/price>30
return $x/title
results in output that looks like this:
<title lang="en">XQuery Kick Start</title> <title lang="en">Learning XML</title>
while sorting with code like this:
for $x in doc( "books.xml" )/bookstore/book
where $x/price>30
order by $x/title
return $x/title
would return output that looks like this:
<title lang="en">Learning XML</title> <title lang="en">XQuery Kick Start</title>
You can also use these techniques to turn out a normal HTML list by using code like this:
<ul>
{
for $x in doc( "books.xml" )/bookstore/book/title
order by $x
return <li>{ $x }</li>
}
</ul>
to get output that looks like this:
<ul> <li><title lang="en">Everyday Italian</title></li> <li><title lang="en">Harry Potter</title></li> <li><title lang="en">Learning XML</title></li> <li><title lang="en">XQuery Kick Start</title></li> </ul>
while using code like this
<ul>
{
for $x in doc( "books.xml" )/bookstore/book/title
order by $x
return <li>{ data( $x ) }</li>
}
</ul>
would show only the data like this:
<ul> <li>Everyday Italian</li> <li>Harry Potter</li> <li>Learning XML</li> <li>XQuery Kick Start</li> </ul>
If/Then/Else expressions (selection) are allowed in XQuery like this ( note that else is required, but may be empty ) :
for $x in doc( "books.xml" )/bookstore/book
return if ( $x/@category="CHILDREN" )
then <child>{ data( $x/title ) }</child>
else <adult>{ data( $x/title ) }</adult>
which would result in output like this:
<adult>Everyday Italian</adult> <child>Harry Potter</child> <adult>XQuery Kick Start</adult> <adult>Learning XML</adult>
Note that comparisons work pretty much as expected:
General comparisons |
Value comparisons |
(Meanings) |
| = | eq | equals |
| != | ne | not equals |
| < | lt | less than |
| <= | le | less than or equals |
| > | gt | greater than |
| >= | ge | greater than or equals |
but also note the differences between the two approaches:
$bookstore//book/@q > 10
Returns true if any q attributes have values greater than 10.
$bookstore//book/@q gt 10
Returns true if there is one and only one q attribute returned by the expression and if its value is greater than 10. An error/exception is thrown if more than one q is returned,.
Sometimes you want to work with elements, perhaps to add one or more elements to the output which were not in the input like this:
<html>
<body>
<h1>Bookstore</h1>
<ul>
{
for $x in doc( "books.xml" )/bookstore/book
order by $x/title
return <li>{ data( $x/title ) }. Category: { data( $x/@category ) }</li>
}
</ul>
</body>
</html>
which would result in output like this:
<html>
<body>
<h1>Bookstore</h1>
<ul>
<li>Everyday Italian. Category: COOKING</li>
<li>Harry Potter. Category: CHILDREN</li>
<li>Learning XML. Category: WEB</li>
<li>XQuery Kick Start. Category: WEB</li>
</ul>
</body>
</html>
Sometimes you want to work with attributes of elements, maybe even creating new ones for the output which were not in the input by doing things like this:
<html>
<body>
<h1>Bookstore</h1>
<ul>
{
for $x in doc( "books.xml" )/bookstore/book
order by $x/title
return <li class="{ data( $x/@category ) }">{ data( $x/title ) }</li>
}
</ul>
</body>
</html>
which would result in output like this:
<html>
<body>
<h1>Bookstore</h1>
<ul>
<li class="COOKING">Everyday Italian</li>
<li class="CHILDREN">Harry Potter</li>
<li class="WEB">Learning XML</li>
<li class="WEB">XQuery Kick Start</li>
</ul>
</body>
</html>
If you can put an expression there, you can put a function call there.
<name>{ uppercase( $booktitle ) }</name>
doc( "books.xml" )/bookstore/book[ substring( title,1,5='Harry' ) ]
let $name := ( substring( $booktitle,1,4 ) )
declare function prefix:function_name($parameter AS datatype)
AS returnDatatype
{
(: ...function code here... :)
};
example:
declare function local:minPrice(
$price as xs:decimal?,
$discount as xs:decimal?)
AS xs:decimal?
{
let $disc := ($price * $discount) div 100
return ($price - $disc)
};
would return:
<minPrice>{ local:minPrice( $book/price, $book/discount ) }</minPrice>
Sometimes you may want to run XSLT against XML from the commandline. It is pretty easy to do this in Java, and the Apache XML Java packages are the "gold standard" in parsing and manipulating XML. A common thing for practitioners to do is to create a shell script, and then to place the script somewhere in a driectory named in the $PATH environmental variable. For example, here is what the script on my machine looks like:
#! /bin/sh java org.apache.xalan.xslt.Process -IN $1 -XSL $2
Obviously, the -IN argument is about the XML data file and the -XSL argument is about what XSL-Transformation file to apply against the data.
Here is an example of applying a transformation from the commandline using the above shell script. In this example, I just send the output to the screen (default STDOUT), but it could just as easily by redirected to a file or piped into another command. Look at the following and ask yourself how you might use this with a fork or exec command from a CGI script.
jeffs@sylvester [ 5 ] transform.sh bib.xml bibPUSH.xsl <html> <head> <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Playing with Bibliographies</title> <link rel="stylesheet" href="bib.css"> </head> <body> <h1>Masters Thesis List</h1> <div> <p> <span class="author">Author:Kurt P. Brown</span> <br> <span class="title">Title:PRPL: A Database Workload Specification Language, v1.3.</span> <br> <span class="year">Year:1992</span> <br> <span class="school">School:Univ. of Wisconsin-Madison</span> <br> </p> </div> <div> <p> <span class="author">Author:Tolga Yurek</span> <br> <span class="title">Title:Efficient View Maintenance at Data Warehouses.</span> <br> <span class="year">Year:1997</span> <br> <span class="school">School:University of California at Santa Barbara, Department of Computer Science</span> <br> </p> </div> <div> <p> <span class="author">Author:Christian Schulte</span> <br> <span class="title">Title:Entwurf und Implementierung eines bersetzenden Systems fur das intuitionistische logische Programmieren auf der Warren Abstract Machine.</span> <br> <span class="year">Year:1991</span> <br> <span class="school">School:Universitat Karlsruhe, Institut fur Logik, Komplexitat und Deduktionssysteme</span> <br> </p> </div> <div> <p> <span class="author">Author:Peter Van Roy</span> <br> <span class="title">Title:A Prolog Compiler for the PLM.</span> <br> <span class="year">Year:1984</span> <br> <span class="school">School:University of California at Berkeley</span> <br> </p> </div> <div> <p> <span class="author">Author:Tatu Ylonen</span> <br> <span class="title">Title:Shadow Paging Is Feasible.</span> <br> <span class="year">Year:1994</span> <br> <span class="school">School:Helsinki University of Technology, Department of Computer Science</span> <br> </p> </div> <h1>PhD Thesis List</h1> <div> <p> <span class="author">Author:Kurt P. Brown</span> <br> <span class="title">Title:PRPL: A Database Workload Specification Language, v1.3.</span> <br> <span class="year">Year:1992</span> <br> <span class="school">School:Univ. of Wisconsin-Madison</span> <br> </p> </div> <div> <p> <span class="author">Author:Tolga Yurek</span> <br> <span class="title">Title:Efficient View Maintenance at Data Warehouses.</span> <br> <span class="year">Year:1997</span> <br> <span class="school">School:University of California at Santa Barbara, Department of Computer Science</span> <br> </p> </div> <div> <p> <span class="author">Author:Christian Schulte</span> <br> <span class="title">Title:Entwurf und Implementierung eines bersetzenden Systems fur das intuitionistische logische Programmieren auf der Warren Abstract Machine.</span> <br> <span class="year">Year:1991</span> <br> <span class="school">School:Universitat Karlsruhe, Institut fur Logik, Komplexitat und Deduktionssysteme</span> <br> </p> </div> <div> <p> <span class="author">Author:Peter Van Roy</span> <br> <span class="title">Title:A Prolog Compiler for the PLM.</span> <br> <span class="year">Year:1984</span> <br> <span class="school">School:University of California at Berkeley</span> <br> </p> </div> <div> <p> <span class="author">Author:Tatu Ylonen</span> <br> <span class="title">Title:Shadow Paging Is Feasible.</span> <br> <span class="year">Year:1994</span> <br> <span class="school">School:Helsinki University of Technology, Department of Computer Science</span> <br> </p> </div> </body> </html> jeffs@sylvester [ 6 ] |
Try using these in your oXygen XML tool. Then try using them from the commandline. In what situations would you want to use one approach rather than another?
Now try doing the Starting with XPath exercise. The data files and sample solutions may be found in the examples directory for this week.
Last modified: 10 Mar 2008 10:40:04 AM