Part I: XPath 2.0
Part II: XSLT 2.0
Part III: XQuery
Used for XSLT 2.0 and XQuery
Schema Aware
Partially implemented by Michael Kay's Saxon 7.0, http://saxon.sourceforge.net/
Simplify manipulation of XML Schema-typed content
Simplify manipulation of string content
Support related XML standards
Improve ease of use
Improve interoperability
Improve internationalization (i18n) support
Maintain backward compatibility
Enable improved processor efficiency
Must express data model in terms of the Infoset
Must provide common core syntax and semantics for XSLT 2.0 and XML Query 1.0
Must support explicit "for any" or "for all" comparison and equality semantics
Must add min()
and max()
functions
Any valid XPath 1.0 expression SHOULD also be a valid XPath 2.0 expression when operating in the absence of XML Schema type information.
Should provide intersection and difference functions
Must loosen restrictions on location steps
Must provide a conditional expression (e.g. ternary
?:
operator in Java and C)
Should support additional string functions, possibly including space padding, string replacement and conversion to upper or lower case
Must support regular expression string matching using the regexp syntax from schemas
Must add support for XML Schema primitive datatypes
Should add support for XML Schema structures
(Adapted from Jeni Tennison)
The first class objects are strings, numbers, booleans, and node-sets (plus result tree fragments for XSLT)
Node-sets contain nodes (which are not first-class objects)
Nodes have various properties, including children - a node set (the order of the children can be worked out from the nodes' document order)
Seven node types: document, element, attribute, text, namespace, processing instruction, and comment
There are conceptually two kinds of node-sets:
Node-sets containing new nodes (result tree fragments) can only be generated using XSLT
Node-sets containing existing nodes can only be generated using XPath
No list data types, only node-sets but no number sets
Not Infoset compatible
(Adapted from Jeni Tennison)
The first class object type is a sequence; i.e. an ordered list
Sequences contain items of two types: simple typed values or nodes. (They may not contain other sequences.)
A sequence containing one item is the same as the item.
Simple typed values have W3C XML Schema Language simple types: xsd:gYear, xsd:int, xsd:decimal, xsd:date, etc.
Seven node types: document, element, attribute, text, namespace, processing instruction, and comment
Nodes have these properties:
node-kind: either "document", "element", "attribute", "text", "namespace", "processing-instruction", or "comment".
name: a sequence containing one expanded QName if the node has a name (elements, attributes, etc.) or an empty sequence if the node doesn't have a name (comments, text nodes, etc.)
parent: a sequence containing the unique parent node; the empty sequence is returned for parentless nodes, particularly document and namespace nodes
base-uri: URI from which this particular node came
string-value: same as XPath 1.0
typed-value: a sequence of simple typed values corresponding to the node (always the empty sequence for anything other than elements and attributes)
A sequence of child nodes (empty except for element and document nodes)
attributes: a sequence of attribute nodes; empty except for attribute nodes
namespaces: a sequence of namespace nodes in-scope on the node
declaration: a sequence containing 0 or 1 schema component
type: a sequence containing 0 or 1 schema component
unique-ID: a sequence containing 0 or 1 xsd:ID type node
Infoset compatible
{-- This is an XPath comment --}
<xsl:apply-templates
select="{-- The difference between the context node and the
current node is crucial here --}
../composition[@composer=current()/@id]"/>
<xsl:template match="*:set">
This matches MathML set elements, SVG set elements, set
elements in no namespace at all, etc.
</xsl:template>
The document()
function returns the root of a document at a given URL
document("http://www.cafeconleche.org/")//today
/child::contacts/(child::personal | child::business)/child::name
Abbreviated: /contacts/(personal | business)/name
Map an IDREF attribute node to the element it refers to
Composers and their compositions are linked through the
an ID-type
id
attribute of the composer
element
and the IDREF-type composer
attribute of the
composition
element:
<composer id="c3"> <name> <first_name>Beth</first_name> <middle_name></middle_name> <last_name>Anderson</last_name> </name> </composer> <composition composers="c3"> <title>Trio: Dream in D</title> <date><year>(1980)</year></date> <length>10'</length> <instruments>fl, pn, vc, or vn, pn, vc</instruments> <description> Rhapsodic. Passionate. Available on CD <cite><a href="http://www.amazon.com/exec/obidos/ASIN/B000007NMH/qid%3D913265342/sr%3D1-2/">Two by Three</a></cite> from North/South Consonance (1998). </description> <publisher></publisher> </composition>
With XPath 1.0:
<xsl:template match="composition">
<h2>
<xsl:value-of select="name"/> by
<xsl:value-of select="../composer[@id=current()/@composer]"/>
</h2>
</xsl:template>
With XPath 2.0:
<xsl:template match="composition">
<h2>
<xsl:value-of select="name"/> by
<xsl:value-of select="@composers=>composer/name"/>
</h2>
</xsl:template>
(1, 3, 2, 34, 76, "fnord")
(1 to 12)
Using constructors: (xf:date("2002-03-11"), xf:date("2002-03-12"), xf:date("2002-03-13"),
xf:date("2002-03-14"), xf:date("2002-03-15"))
Sequences can have mixed types: (xf:date("2002-03-11"), "Hello", 15)
Sequences do not nest; that is, a sequence cannot be a member of a sequence
Sequences are not sets: they are ordered and can contain duplicates
A single item is the same as a one-element sequence containing th
<?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <numbers> <xsl:for-each select="(1 to 10)"> <integer> <xsl:value-of select="."/> </integer> </xsl:for-each> </numbers> </xsl:template> </xsl:stylesheet>
Output (modulo white space):
<?xml version="1.0" encoding="utf-8"?>
<numbers>
<integer>1</integer>
<integer>2</integer>
<integer>3</integer>
<integer>4</integer>
<integer>5</integer>
<integer>6</integer>
<integer>7</integer>
<integer>8</integer>
<integer>9</integer>
<integer>10</integer>
</numbers>
union
or |
Duplicates are eliminated
<?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="/"> <numbers> <xsl:for-each select='(3 to 10) | (5 to 12) | (20 to 23)'> <integer> <xsl:value-of select="."/> </integer> </xsl:for-each> </numbers> </xsl:template> </xsl:stylesheet>
Output:
<numbers>
<integer>3</integer>
<integer>4</integer>
<integer>5</integer>
<integer>6</integer>
<integer>7</integer>
<integer>8</integer>
<integer>9</integer>
<integer>10</integer>
<integer>11</integer>
<integer>12</integer>
<integer>20</integer>
<integer>21</integer>
<integer>22</integer>
<integer>23</integer>
</numbers>
intersect
<?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="/"> <numbers> <xsl:for-each select='(3 to 10) intersect (5 to 12)'> <integer> <xsl:value-of select="."/> </integer> </xsl:for-each> </numbers> </xsl:template> </xsl:stylesheet>
Output:
<numbers>
<integer>5</integer>
<integer>6</integer>
<integer>7</integer>
<integer>8</integer>
<integer>9</integer>
<integer>10</integer>
</numbers>
except
<?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="/"> <numbers> <xsl:for-each select='(3 to 10) except (5 to 12)'> <integer> <xsl:value-of select="."/> </integer> </xsl:for-each> </numbers> </xsl:template> </xsl:stylesheet>
Output:
<numbers>
<integer>3</integer>
<integer>4</integer>
</numbers>
Compare single values and sequences of single or no values:
eq
ne
lt
le
gt
ge
These operators return either true, false, the empty sequence, an error, or a type exception.
Differ from value comparisons in that the condition only need to be true for some pair of items in a sequence
=
!=
<
<=
>
>=
These operators always return either true or false.
== and != have the same semantics as Java's == operator (identity), not the
equals()
method (equality)
>> and << compare single nodes and sequences of single nodes for document order
The precedes
operator returns true
if the first operand node is reachable from the second operand node
using the
preceding axis; otherwise it returns false.
The follows
operator returns true
if the first operand node is reachable from the second operand node
using the following axis; otherwise it returns false.
Useful for joining documents
Useful for restructuring data.
Syntax:
for $var1 in expression, $var2 in expression...
return expression
Consider the list of weblogs at http://static.userland.com/weblogMonitor/logs.xml
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE foo SYSTEM "http://msdn.microsoft.com/xml/general/htmlentities.dtd"> <weblogs> <log> <name>MozillaZine</name> <url>http://www.mozillazine.org</url> <changesUrl>http://www.mozillazine.org/contents.rdf</changesUrl> <ownerName>Jason Kersey</ownerName> <ownerEmail>kerz@en.com</ownerEmail> <description>THE source for news on the Mozilla Organization. DevChats, Reviews, Chats, Builds, Demos, Screenshots, and more.</description> <imageUrl></imageUrl> <adImageUrl>http://static.userland.com/weblogMonitor/ads/kerz@en.com.gif</adImageUrl> </log> <log> <name>SalonHerringWiredFool</name> <url>http://www.salonherringwiredfool.com/</url> <ownerName>Some Random Herring</ownerName> <ownerEmail>salonfool@wiredherring.com</ownerEmail> <description></description> </log> <log> <name>SlashDot.Org</name> <url>http://www.slashdot.org/</url> <ownerName>Simply a friend</ownerName> <ownerEmail>afriendofweblogs@weblogs.com</ownerEmail> <description>News for Nerds, Stuff that Matters.</description> </log> </weblogs>
The changesUrl
element points to a document like
this:
<?xml version="1.0"?> <!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd"> <rss version="0.91"> <channel> <title>MozillaZine</title> <link>http://www.mozillazine.org/</link> <language>en-us</language> <description>Your source for Mozilla news, advocacy, interviews, builds, and more!</description> <copyright>Copyright 1998-2002, The MozillaZine Organization</copyright> <managingEditor>jason@mozillazine.org</managingEditor> <webMaster>jason@mozillazine.org</webMaster> <image> <title>MozillaZine</title> <url>http://www.mozillazine.org/image/mynetscape88.gif</url> <description>Your source for Mozilla news, advocacy, interviews, builds, and more!</description> <link>http://www.mozillazine.org/</link> </image> <item> <title>BugDays Are Back!</title> <link>http://www.mozillazine.org/talkback.html?article=2151</link> </item> <item> <title>Independent Status Reports</title> <link>http://www.mozillazine.org/talkback.html?article=2150</link> </item> </channel> </rss>
We want to process all the item
elements from each weblog.
<xsl:template match="weblogs">
<xsl:apply-templates select="
for $url in log/changesUrl
return document($url)/item
"/>
</xsl:template>
if ( expression) then expression else expression
Not all weblogs have a changesUrl
<xsl:template match="log">
<xsl:apply-templates select="
if (changesUrl)
then document(changesUrl)
else document(url)"/>
</xsl:template>
some $QualifedName in expression satisfies
expression
every $QualifedName in expression satisfies
expression
Both return boolean values, true or false
<xsl:template match="weblogs">
<xsl:if test="some $log in log satisfies changesURL">
????
</xsl:if>
</xsl:template>
<xsl:template match="weblogs">
<xsl:if test="every $log in log satisfies url">
????
</xsl:if>
</xsl:template>
Functions are in the
http://www.w3.org/2001/12/xquery-functions
namespace which is customarily mapped to the xf
prefix
The function namespace name and prefix is understood in XSLT, without being explicitly stated.
Operators are in the http://www.w3.org/2001/12/xquery-operators namespace
XPath implementations such as XQuery and XSLT map the operators to symbols like * and +
xf:node-kind(Node)
xf:name(Node)
xf:string(Object)
xf:data(Node)
xf:base-uri(node)
xf:unique-ID(element)
Create a simple type from a string
Numeric constructors:
xf:decimal(string $srcval) => decimal
xf:integer(string $srcval) => integer
xf:long(string $srcval) => integer
xf:int(string $srcval) => integer
xf:short(string $srcval) => integer
xf:byte(string $srcval) => integer
xf:float(string $srcval) => float
xf:double(string $srcval) => double
String constructors
xf:string(string $srcval) => string
xf:normalizedString(string $srcval) => normalizedString
xf:token(string $srcval) => token
xf:language(string $srcval) => language
xf:Name(string $srcval) => Name
xf:NMTOKEN(string $srcval) => NMTOKEN
xf:NCName(string $srcval) => NCName
xf:ID(string $srcval) => ID
xf:IDREF(string $srcval) => IDREF
xf:ENTITY(string $srcval) => ENTITY
Boolean constructors:
xf:true() => boolean
xf:false() => boolean
xf:boolean-from-string(string $srcval) => boolean
Duration and Datetime constructors:
xf:duration(string $srcval) => duration
xf:dateTime(string $srcval) => dateTime
xf:date(string $srcval) => date
xf:time(string $srcval) => time
xf:gYearMonth(string $srcval) => gYearMonth
xf:gYear(string $srcval) => gYear
xf:gMonthDay(string $srcval) => gMonthDay
xf:gMonth(string $srcval) => gMonth
xf:gDay(string $srcval) => gDay
Constructors for QNames
xf:QName-from-uri(string $paramURI, string $paramLocal) => QName
xf:QName-from-string(string $param) => QName
xf:QName(string $paramLocal) => QName
Constructor for anyURI:
xf:anyURI(string $srcval) => anyURI
Constructors for NOTATION:
xf:NOTATION(string $srcval) => NOTATION
op:multiply(numeric $operand1, numeric $operand2) => numeric
op:numeric-add(numeric $operand1, numeric $operand2) => numeric
op:numeric-subtract(numeric $operand1, numeric $operand2) => numeric
op:numeric-multiply(numeric $operand1, numeric $operand2) => numeric
op:numeric-divide(numeric $operand1, numeric $operand2) => numeric
op:numeric-mod(numeric $operand1, numeric $operand2) => numeric
op:numeric-unary-plus(numeric $operand) => numeric
op:numeric-unary-minus(numeric $operand) => numeric
op:numeric-equal(numeric $operand1, numeric $operand2) => boolean
op:numeric-less-than(numeric $operand1, numeric $operand2) => boolean
op:numeric-greater-than(numeric $operand1, numeric $operand2) => boolean
op:numeric-less-than-or-equal(numeric $operand1, numeric $operand2) => boolean
op:numeric-greater-than-or-equal(numeric $operand1, numeric $operand2) => boolean
op:numeric-not-equal(numeric $operand1, numeric $operand2) => boolean
xf:floor(double? $srcval) => integer?
xf:ceiling(double? $srcval) => integer?
xf:round(double? $srcval) => integer?
xf:compare(string? $comparand1, string? $comparand2) => integer?
xf:compare(string? $comparand1, string? $comparand2, anyURI $collationLiteral) => integer?
xf:concat() => string
xf:concat(string? $op1) => string
xf:concat(string? $op1, string? $op2, ...) => string
xf:starts-with(string? $operand1, string? $operand2) => boolean?
xf:starts-with(string? $operand1, string? $operand2, anyURI $collationLiteral) => boolean?
xf:ends-with(string? $operand1, string? $operand2) => boolean?
xf:ends-with(string? $operand1, string? $operand2, anyURI $collationLiteral) => boolean?
xf:contains(string? $operand1, string? $operand2) => boolean?
xf:contains(string? $operand1, string? $operand2, anyURI $collationLiteral) => boolean?
xf:substring(string? $sourceString, decimal? $startingLoc) => string?
xf:substring(string? $sourceString, decimal? $startingLoc, decimal? $length) => string?
xf:string-length(string? $srcval) => integer?
xf:substring-before(string? $operand1, string? $operand2) => string?
xf:substring-before(string? $operand1, string? $operand2, anyURI $collationLiteral) => string?
xf:substring-after(string? $operand1, string? $operand2) => string?
xf:substring-after(string? $operand1, string? $operand2, anyURI $collationLiteral) => string?
xf:normalize-space(string? $srcval) => string?
xf:normalize-unicode(string? $srcval, string $normalizationForm) => string?
xf:upper-case(string? $srcval) => string?
xf:lower-case(string? $srcval) => string?
xf:translate(string? $srcval, string? $mapString, string? $transString) => string?
xf:string-pad(string? $padString, decimal? $padCount) => string?
xf:match(string? $srcval, string? $regexp) => integer*
xf:replace(string? $srcval, string? $regexp, string? $repval) => string?
Syntax for xf:match()
is based on W3C XML Schema Language
regular expressions:
Syntax for xf:replace()
is based
on W3C XML Schema Language
regular expressions plus $N
in replace patterns to indicate the
Nth match.
op:boolean-and(boolean $value1, boolean $value2) => boolean
op:boolean-or(boolean $value1, boolean $value2) => boolean
op:boolean-equal(boolean? $value1, boolean? $value2) => boolean?
xf:not(boolean? $srcval) => boolean
xf:not3(boolean? $srcval) => boolean?
Comparisons of Duration and Datetime Values:
op:duration-equal(duration $operand1, duration $operand2) => boolean
op:duration-less-than(duration $operand1, duration $operand2) => boolean
op:duration-greater-than(duration $operand1, duration $operand2) => boolean
op:duration-less-than-or-equal(duration $operand1, duration $operand2) => boolean
op:duration-greater-than-or-equal(duration $operand1, duration $operand2) => boolean
op:duration-not-equal(duration $operand1, duration $operand2) => boolean
op:datetime-equal(dateTime $operand1, dateTime $operand2) => boolean
op:datetime-less-than(dateTime $operand1, dateTime $operand2) => boolean
op:datetime-greater-than(dateTime $operand1, dateTime $operand2) => boolean
op:datetime-less-than-or-equal(dateTime $operand1, dateTime $operand2) => boolean
op:datetime-greater-than-or-equal(dateTime $operand1, dateTime $operand2) => boolean
op:datetime-not-equal(dateTime $operand1, dateTime $operand2) => boolean
Component Extraction Functions on Datetime Values:
xf:get-Century-from-dateTime(dateTime? $srcval) => integer?
xf:get-Century-from-date(date? $srcval) => integer?
xf:get-hour-from-dateTime(dateTime? $srcval) => integer?
xf:get-hour-from-time(time? $srcval) => integer?
xf:get-minutes-from-dateTime(dateTime? $srcval) => integer?
xf:get-minutes-from-time(time? $srcval) => integer?
xf:get-seconds-from-dateTime(dateTime? $srcval) => decimal?
xf:get-seconds-from-time(time? $srcval) => decimal?
xf:get-timezone-from-dateTime(dateTime? $srcval) => string?
xf:get-timezone-from-date(date? $srcval) => string?
xf:get-timezone-from-time(time? $srcval) => string?
Arithmetic Functions on Dates:
xf:add-days(date? $dateParam, decimal? $incrDays) => date?
Functions and Operators on TimePeriod Values:
op:get-duration(dateTime $parameter1, dateTime $parameter2) => duration
op:get-end-dateTime(dateTime $parameter1, duration $parameter2) => dateTime
xf:get-start-dateTime(dateTime $parameter1, duration $parameter2) => dateTime?
xf:get-local-name(QName? $srcval) => string?
xf:get-namespace-uri(QName? $srcval) => anyURI?
op:hex-binary-equal(hexBinary $value1, hexBinary $value2) => boolean
op:base64-binary-equal(base64Binary $value1, base64Binary $value2) => boolean
xf:local-name() => string
xf:local-name(node $srcval) => string
xf:number() => anySimpleType
xf:number(node $srcval) => anySimpleType
op:node-equal(node $parameter1, node $parameter2) => boolean
xf:deep-equal(node $parameter1, node $parameter2) => boolean
xf:deep-equal(node $parameter1, node $parameter2, anyURI $collation) => boolean
op:node-before(node $parameter1, node $parameter2) => boolean
op:node-after(node $parameter1, node $parameter2) => boolean
xf:copy(node? $srcval) => node?
xf:shallow(node? $srcval) => node?
xf:if-absent((elementNode | attributeNode)? $node, anySimpleType $value) => (elementNode | attributeNode | anySimpleType)?
xf:if-empty((elementNode | attributeNode)? $node, anySimpleType $value) => (elementNode | attributeNode | anySimpleType)
op:to(decimal $firstval, decimal $lastval) => sequence
xf:boolean(item* $srcval) => boolean
op:concatenate(item* $seq1, item* $seq2) => item*
op:item-at(item* $seqParam, decimal $posParam) => item?
xf:index-of(item* $seqParam, item $srchParam) => unsignedInt?
xf:index-of(item* $seqParam, item $srchParam, anyURI $collationLiteral) => unsignedInt?
xf:empty(item* $srcval) => boolean
xf:exists(item* $srcval) => boolean
xf:distinct-nodes(node* $srcval) => node*
xf:distinct-values(item* $srcval) => item*
xf:distinct-values(item* $srcval, anyURI $collationLiteral) => item*
xf:insert(item* $target, decimal $position, item* $inserts) => item*
xf:remove(item* $target, decimal $position) => item*
xf:sublist(item* $sourceSeq, decimal $startingLoc) => item*
xf:sublist(item* $sourceSeq, decimal $startingLoc, decimal $length) => item*
xf:sequence-deep-equal(item* $parameter1, item* $parameter2) => boolean?
xf:sequence-deep-equal(item* $parameter1, item* $parameter2, anyURI $collationLiteral) => boolean?
xf:sequence-node-equal(item*? $parameter1, item*? $parameter2) => boolean?
op:union(item* $parameter1, item* $parameter2) => item*
op:intersect(item* $parameter1, item* $parameter2) => item*
op:except(item* $parameter1, item* $parameter2) => item*
xf:count(item* $srcval) => unsignedInt
xf:avg(item* $srcval) => double?
xf:max(item* $srcval) => anySimpleType?
xf:max(item* $srcval, anyURI $collationLiteral) => anySimpleType?
xf:min(item* $srcval) => anySimpleType?
xf:min(item* $srcval, anyURI $collationLiteral) => anySimpleType?
xf:sum(item* $srcval) => double?
xf:id(IDREF* $srcval) => elementNode*
xf:idref(string* $srcval) => elementNode*
xf:filter(expression $srcval) => node*
xf:document(string? $srcval) => node?
op:context-item() => item
xf:position() => unsignedInt
xf:last() => unsignedInt
op:context-document() => DocumentNode
xf:current-dateTime() => dateTime
Uses XPath 2.0
Schema Aware
Partially implemented by Michael Kay's Saxon 7.0, http://saxon.sourceforge.net/
Simplify manipulation of XML Schema-typed content
Simplify manipulation of string content
Support related XML standards
Improve ease of use
Improve interoperability
Improve i18n support
Maintain backward compatibility
Enable improved processor efficiency
Simplifying the ability to parse unstructured information to produce structured results.
Turning XSLT into a general-purpose programming language
Must maintain backwards compatibility with XSLT 1.1
Should be able to match elements and attributes whose value is explicitly null.
Should allow included documents to encapsulate local stylesheets
Could support accessing infoset items for XML declaration
Could provide qualified name aware string functions
Could enable constructing a namespace with computed name
Could simplify resolving prefix conflicts in qname-valued attributes
Could support XHTML output method
Must allow matching on default namespace without explicit prefix
Must add date formatting functions
Must simplify accessing IDs and keys in other documents
Should provide function to absolutize relative URIs
Should include unparsed text from an external resource
Should allow authoring extension functions in XSLT
Should output character entity references instead of numeric character entities
Should construct entity reference by name
Should support Unicode string normalization
Should standardize extension element language bindings
Could improve efficiency of transformations on large documents
Could support reverse IDREF attributes
Could support case-insensitive comparisons
Could support lexigraphic string comparisons
Could allow comparing nodes based on document order
Could improve support for unparsed entities
Could allow processing a node with the "next best matching" template
Could make coercions symmetric by allowing scalar to nodeset conversion
Must support XML schema
Must simplify constructing and copying typed content
Must support sorting nodes based on XML schema type
Could support scientific notation in number formatting
Could provide ability to detect whether "rich" schema information is available
Must simplify grouping
Multiple output documents
Variables can be set to node sets; no more result tree fragments.
Existing elements and functions hardly change at all
Namespace is still http://www.w3.org/1999/XSL/Transform
version
attribute of
xsl:stylesheet
has value 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Top level elements -->
</xsl:stylesheet>
The result tree fragment data-type has been eliminated.
Variable-binding elements with content now construct node-sets
These node sets can now be operated on by templates
Functionality previously available with
saxon:nodeSet()
and similar extension functions
Allows pipelining of templates
Like xsl:for-each
, but orders elements differently
Works well with flat structures
Replaces Muenchian method
Basic syntax:
<xsl:for-each-group
select = expression
group-by = "string expression"
group-adjacent = "string expression"
group-starting-with = pattern>
<!-- Content: (xsl:sort*, content-constructor) -->
</xsl:for-each-group>
The select
attribute selects the population to be grouped.
The group-by
attribute calculates a string value for each node in the population.
Nodes with the same value are grouped together.
The group-adjacent
attribute
calculates a string value for each node in the population.
Every time the value changes, a new group is started.
The group-starting-with
starts a new group
every time its pattern is matched.
group-by
, group-adjacent
,
and group-starting-with
are mutually exclusive.
Task: Arrange articles in a large, flat document like this by section:
<?xml version="1.0"?> <backslash> <story> <title>ROX Desktop Update</title> <url>http://slashdot.org/article.pl?sid=02/02/18/180240</url> <time>2002-02-18 18:50:13</time> <author>timothy</author> <department>small-simple-swift</department> <topic>104</topic> <comments>32</comments> <section>developers</section> <image>topicx.jpg</image> </story> <story> <title>HP Selling Systems With Linux</title> <url>http://slashdot.org/article.pl?sid=02/02/18/1712241</url> <time>2002-02-18 17:37:20</time> <author>timothy</author> <department>wish-this-wasn't-remarkable</department> <topic>173</topic> <comments>188</comments> <section>articles</section> <image>topichp.gif</image> </story> <story> <title>Excellent Hacks to the ReplayTV 4000</title> <url>http://slashdot.org/article.pl?sid=02/02/18/1619213</url> <time>2002-02-18 16:46:04</time> <author>CmdrTaco</author> <department>hardware-I-lust-after</department> <topic>129</topic> <comments>117</comments> <section>articles</section> <image>topictv.jpg</image> </story> <story> <title>Peek-a-Boo(ty)</title> <url>http://slashdot.org/article.pl?sid=02/02/18/1546226</url> <time>2002-02-18 15:58:06</time> <author>Hemos</author> <department>pirate-treasure</department> <topic>158</topic> <comments>207</comments> <section>articles</section> <image>topicprivacy.gif</image> </story> <story> <title>Self-Shredding E-Mail</title> <url>http://slashdot.org/article.pl?sid=02/02/18/1343202</url> <time>2002-02-18 14:37:45</time> <author>timothy</author> <department>plausible-deniability</department> <topic>158</topic> <comments>170</comments> <section>articles</section> <image>topicprivacy.gif</image> </story> <story> <title>CIA &amp; KGB Gadgets On Display</title> <url>http://slashdot.org/article.pl?sid=02/02/18/0252219</url> <time>2002-02-18 13:52:04</time> <author>Hemos</author> <department>looking-a-tthe-gear</department> <topic>126</topic> <comments>103</comments> <section>articles</section> <image>topictech2.gif</image> </story> <story> <title>Re-Building the Wright Flyer</title> <url>http://slashdot.org/article.pl?sid=02/02/18/060257</url> <time>2002-02-18 12:29:12</time> <author>timothy</author> <department>we-hope-they-wear-modern-helmets</department> <topic>126</topic> <comments>132</comments> <section>science</section> <image>topictech2.gif</image> </story> <story> <title>How to Fix the Unix Configuration Nightmare</title> <url>http://slashdot.org/article.pl?sid=02/02/18/0248248</url> <time>2002-02-18 10:48:36</time> <author>Hemos</author> <department>fixing-the-problem</department> <topic>130</topic> <comments>367</comments> <section>articles</section> <image>topicunix.jpg</image> </story> <story> <title>Sleep Less, Live Longer</title> <url>http://slashdot.org/article.pl?sid=02/02/18/0511253</url> <time>2002-02-18 07:38:15</time> <author>timothy</author> <department>if-you're-reading-this</department> <topic>134</topic> <comments>309</comments> <section>science</section> <image>topicscience.gif</image> </story> <story> <title>Warming and Slowing the World</title> <url>http://slashdot.org/article.pl?sid=02/02/18/0243253</url> <time>2002-02-18 04:39:39</time> <author>Hemos</author> <department>slowing-things-down</department> <topic>134</topic> <comments>312</comments> <section>science</section> <image>topicscience.gif</image> </story> </backslash>
<?xml version="1.0"?> <forwardslash> <section> <title>developers</title> <story> <title>ROX Desktop Update</title> <url>http://slashdot.org/article.pl?sid=02/02/18/180240</url> <time>2002-02-18 18:50:13</time> <author>timothy</author> <department>small-simple-swift</department> <topic>104</topic> <comments>32</comments> <image>topicx.jpg</image> </story> </section> <section> <title>articles</title> <story> <title>HP Selling Systems With Linux</title> <url>http://slashdot.org/article.pl?sid=02/02/18/1712241</url> <time>2002-02-18 17:37:20</time> <author>timothy</author> <department>wish-this-wasn't-remarkable</department> <topic>173</topic> <comments>188</comments> <image>topichp.gif</image> </story> <story> <title>Excellent Hacks to the ReplayTV 4000</title> <url>http://slashdot.org/article.pl?sid=02/02/18/1619213</url> <time>2002-02-18 16:46:04</time> <author>CmdrTaco</author> <department>hardware-I-lust-after</department> <topic>129</topic> <comments>117</comments> <image>topictv.jpg</image> </story> <story> <title>Peek-a-Boo(ty)</title> <url>http://slashdot.org/article.pl?sid=02/02/18/1546226</url> <time>2002-02-18 15:58:06</time> <author>Hemos</author> <department>pirate-treasure</department> <topic>158</topic> <comments>207</comments> <image>topicprivacy.gif</image> </story> <story> <title>Self-Shredding E-Mail</title> <url>http://slashdot.org/article.pl?sid=02/02/18/1343202</url> <time>2002-02-18 14:37:45</time> <author>timothy</author> <department>plausible-deniability</department> <topic>158</topic> <comments>170</comments> <image>topicprivacy.gif</image> </story> <story> <title>CIA &amp; KGB Gadgets On Display</title> <url>http://slashdot.org/article.pl?sid=02/02/18/0252219</url> <time>2002-02-18 13:52:04</time> <author>Hemos</author> <department>looking-a-tthe-gear</department> <topic>126</topic> <comments>103</comments> <image>topictech2.gif</image> </story> <story> <title>How to Fix the Unix Configuration Nightmare</title> <url>http://slashdot.org/article.pl?sid=02/02/18/0248248</url> <time>2002-02-18 10:48:36</time> <author>Hemos</author> <department>fixing-the-problem</department> <topic>130</topic> <comments>367</comments> <image>topicunix.jpg</image> </story> </section> <section> <title>science</title> <story> <title>Re-Building the Wright Flyer</title> <url>http://slashdot.org/article.pl?sid=02/02/18/060257</url> <time>2002-02-18 12:29:12</time> <author>timothy</author> <department>we-hope-they-wear-modern-helmets</department> <topic>126</topic> <comments>132</comments> <image>topictech2.gif</image> </story> <story> <title>Sleep Less, Live Longer</title> <url>http://slashdot.org/article.pl?sid=02/02/18/0511253</url> <time>2002-02-18 07:38:15</time> <author>timothy</author> <department>if-you're-reading-this</department> <topic>134</topic> <comments>309</comments> <section>science</section> <image>topicscience.gif</image> </story> <story> <title>Warming and Slowing the World</title> <url>http://slashdot.org/article.pl?sid=02/02/18/0243253</url> <time>2002-02-18 04:39:39</time> <author>Hemos</author> <department>slowing-things-down</department> <topic>134</topic> <comments>312</comments> <section>science</section> <image>topicscience.gif</image> </story> </section> </forwardslash>
<?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <forwardslash> <xsl:apply-templates select="*"/> </forwardslash> </xsl:template> <xsl:template match="backslash"> <xsl:for-each-group select="story" group-by="section"> <section> <title><xsl:value-of select="current-group()/section"/></title> <xsl:apply-templates select="."/> </section> </xsl:for-each-group> </xsl:template> <xsl:template match="story"> <story> <xsl:apply-templates/> </story> </xsl:template> <xsl:template match="*"> <xsl:copy-of select="."/> </xsl:template> <xsl:template match="section"/> </xsl:stylesheet>
Determines the URI of the principal result tree; i.e. the main output document
Syntax:
<!-- Category: declaration -->
<xsl:destination
format = "QualifiedName"
href = "uri-reference" />
The format attribute names an xsl:output
element
for this result document.
Determines the URI of a secondary result tree; there can be several of these.
Allows you to generate multiple documents from one source document
Previously available with extension functions like
xt:document
and saxon:output
Syntax:
<!-- Category: instruction -->
<xsl:result-document
format = "QualifiedName"
href = "uri-reference">
<!-- Content: content-constructor -->
</xsl:result-document>
The format attribute names an xsl:output
element
for this result document.
<xsl:output name="ccl:html" method="html" encoding="ISO-8859-1" />
<xsl:result-document href="index.html" format="ccl:html">
<html>
<head>
<title><xsl:value-of select="title"/></title>
</head>
<body>
<h1 align="center"><xsl:value-of select="title"/></h1>
<ul>
<xsl:for-each select="slide">
<li><a href="{format-number(position(),'00')}.html"><xsl:value-of select="title"/></a></li>
</xsl:for-each>
</ul>
<p><a href="{translate(title,' ', '_')}.html">Entire Presentation as Single File</a></p>
<hr/>
<div align="center">
<A HREF="01.html">Start</A> | <A HREF="/xml/">Cafe con Leche</A>
</div>
<hr/>
<font size="-1">
Copyright 2002
<a href="http://www.elharo.com/">Elliotte Rusty Harold</a><br/>
<a href="mailto:elharo@metalab.unc.edu">elharo@metalab.unc.edu</a><br/>
Last Modified <xsl:apply-templates select="last_modified" mode="lm"/>
</font>
</body>
</html>
</xsl:result-document>
<xsl:sort-key
name = "Qualified Name">
<!-- Content: (xsl:sort+) -->
</xsl:sort-key>
Attaches an additional namespace node to a result tree element
Rarely necessary; normally the usual XSLT 1.0 namespace declarations are sufficient.
Occasionally useful if the output document uses a namespace prefix exclusively in element content or attribute values
<xsl:namespace name="xsd">http://www.w3.org/2001/XMLSchema</xsl:namespace>
Separator attribute identifies value placed between string value of each member of sequence
<x><xsl:value-of select="(1,2,3,4)" separator=" | "/></x>
<x>1 | 2 | 3 | 4</x>
An attribute that specifies the default namespace in effect for unprefixed element names used in XPath expressions within this element and its descendants
Can be used on literal result elements, in which case it is
in the XSLT namespace and the attribute is prefixed as
xsl:default-xpath-namespace
XPath expressions must use a prefix to match XHTML element names.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml" > <xsl:output method="html" encoding="ISO-8859-1"/> <xsl:template match="week"> <html xml:lang="en" lang="en"> <head><title><xsl:value-of select="//html:h1[1]"/></title></head> <body bgcolor="#ffffff" text="#000000"> <xsl:apply-templates select="html:body"/> <font size="-1">Last Modified Mon June 5, 2001<br /> Copyright 2001 Elliotte Rusty Harold<br /> <a href="mailto:elharo@metalab.unc.edu">elharo@metalab.unc.edu</a> </font> </body> </html> </xsl:template> <xsl:template match="html:body"> <xsl:apply-templates select="text()[count(following-sibling::html:hr)>1]|*[count(following-sibling::html:hr)>1]" /> <hr/> </xsl:template> <xsl:template match="html:*"> <xsl:copy> <xsl:for-each select="@*"> <xsl:copy-of select="."/> </xsl:for-each> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="html:font[@size='-1']"></xsl:template> <xsl:template match="html:a"> <xsl:apply-templates/> </xsl:template> <xsl:template match="html:applet"> <xsl:apply-templates/> </xsl:template> <xsl:template match="html:param"/> </xsl:stylesheet>
XPath expressions can use customary, non-prefixed XHTML element names.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" default-xpath-namespace="http://www.w3.org/1999/xhtml" > <xsl:output method="html" encoding="ISO-8859-1"/> <xsl:template match="week"> <html xml:lang="en" lang="en"> <head><title><xsl:value-of select="//h1[1]"/></title></head> <body bgcolor="#ffffff" text="#000000"> <xsl:apply-templates select="body"/> <font size="-1">Last Modified Mon June 5, 2001<br /> Copyright 2001 Elliotte Rusty Harold<br /> <a href="mailto:elharo@metalab.unc.edu">elharo@metalab.unc.edu</a> </font> </body> </html> </xsl:template> <xsl:template match="body"> <xsl:apply-templates select="text()[count(following-sibling::hr)>1]|*[count(following-sibling::hr)>1]"/> <hr/> </xsl:template> <xsl:template match="*"> <xsl:copy> <xsl:for-each select="@*"> <xsl:copy-of select="."/> </xsl:for-each> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="font[@size='-1']"></xsl:template> <xsl:template match="a"> <xsl:apply-templates/> </xsl:template> <xsl:template match="applet"> <xsl:apply-templates/> </xsl:template> <xsl:template match="param"/> </xsl:stylesheet>
Top-level elements in some namespace other than the XSLT namespace (No namespace is not allowed.)
Exact interpretation is processor specific, but may not change the meaning of cusotmary elements
Possible uses:
Data for extension instructions and extension functions
Information about what to do with the result tree
Information about how to obtain the source tree
Optimization hints
Metadata about the stylesheet
Documentation for the stylesheet
Variables can have a type:
Syntax:
<xsl:variable
name = "QualifiedName"
select = expression
type = datatype>
<!-- Content: content-constructor -->
</xsl:variable>
<xsl:param
name = "QualifiedName"
select = expression
type = datatype>
<!-- Content: content-constructor -->
</xsl:param>
Constants for types remain to be determined
<xsl:function name="math:factorial"
xmlns:fib="http://www.example.com/math"
exclude-result-prefixes="math">
<xsl:param name="index" type="xsd:nonNegativeInteger"/>
<xsl:result type="xsd:positiveInteger"
select="if ($sentence eq 0) then 1
else math:factorial(index - 1)/>
</xsl:function>
sequence unparsed-text(sequence uris, String encoding?)
For example,
<include_as_text source="bib.xml"/>
<xsl:template match="include_as_text">
<xsl:value-of select="unparsed-text(@source)"/>
</xsl:template>
Three parts:
A data model for XML documents based on the XML Infoset
A mathematically precise query algebra; that is, a set of query operators on that data model
A query language based on these query operators and this algebra
A fourth generation declarative language like SQL; not a procedural language like Java or a functional language like XSLT
Queries operate on single documents or fixed collections of documents.
Queries select whole documents or subtrees of documents that match conditions defined on document content and structure
Can construct new documents based on what is selected
No updates or inserts!
Narrative documents and collections of such documents; e.g. generate a table of contents for a book
Data-oriented documents; e.g. SQL-like queries of an XML dump of a database
Filtering streams to process logs of email messages, network packets, stock market data, newswire feeds, EDI, or weather data to filter and route messages represented in XML, to extract data from XML streams, or to transform data in XML streams.
XML views of non-XML data
Files on a disk
Native-XML databases like Software AG's Tamino
DOM trees in memory
Streaming data
Other representations of the infoset
Direct query tools at command line
GUI query tools
JSP, ASP, PHP, and other such server side technologies
Programs written in Java, C++, and other languages that need to extract data from XML documents
Others are possible
Anywhere SQL is used to extract data from a database, XQuery is used to extract data from an XML document.
SQL is a non-compiled language that must be processed by some other tool to extract data from a database. So is XQuery.
A relational database contains tables | An XML database contains collections |
A relational table contains records with the same schema | A collection contains XML documents with the same DTD |
A relational record is an unordered list of named values | An XML document is a tree of nodes |
A SQL query returns an unordered set of records | An XQuery returns an unordered sequence of nodes |
XML 1.0 #PCDATA
Schema primitive types: positiveInteger, String, float, double, unsignedLong, gYear, date, time, boolean, etc.
Schema complex types
Collections of these types
References to these types
Most of the examples in this talk query this bibliography document at the (relative) URL bib.xml:
<bib> <book year="1994"> <title>TCP/IP Illustrated</title> <author><last>Stevens</last><first>W.</first></author> <publisher>Addison-Wesley</publisher> <price> 65.95</price> </book> <book year="1992"> <title>Advanced Programming in the Unix Environment</title> <author><last>Stevens</last><first>W.</first></author> <publisher>Addison-Wesley</publisher> <price>65.95</price> </book> <book year="2000"> <title>Data on the Web</title> <author><last>Abiteboul</last><first>Serge</first></author> <author><last>Buneman</last><first>Peter</first></author> <author><last>Suciu</last><first>Dan</first></author> <publisher>Morgan Kaufmann Publishers</publisher> <price> 39.95</price> </book> <book year="1999"> <title>The Economics of Technology and Content for Digital TV</title> <editor> <last>Gerbarg</last><first>Darcy</first> <affiliation>CITI</affiliation> </editor> <publisher>Kluwer Academic Publishers</publisher> <price>129.95</price> </book> </bib>
Adapted from Mary Fernandez, Jerome Simeon, and Phil Wadler: XML Query Languages: Experiences and Exemplars, 1999, as adapted in XML Query Use Cases
FOR
: each node selected by an XPath 2.0 location path
LET
: a new variable have a specified value
WHERE
: a condition expressed in XPath is true
RETURN
: this node set
FOR $t IN document("bib.xml")/bib/book/title
RETURN
$t
Adapted from XML Query Use Cases
<title>TCP/IP Illustrated</title>
<title>Advanced Programming in the Unix Environment</title>
<title>Data on the Web</title>
<title>The Economics of Technology and Content for Digital TV</title>
Adapted from XML Query Use Cases
An XML Syntax for XQuery
Intended for machine processing and programmer convenience, not for human legibility
In XQuery:
FOR $t IN document("bib.xml")/bib/book/title
RETURN
$t
In XQueryX:
<?xml version="1.0"?>
<xq:query xmlns:xq="http://www.w3.org/2001/06/xqueryx">
<xq:flwr>
<xq:forAssignment variable="$t">
<xq:step axis="CHILD">
<xq:function name="document">
<xq:constant datatype="CHARSTRING">bib.xml</xq:constant>
</xq:function>
<xq:identifier>bib</xq:identifier>
</xq:step>
<xq:step axis="CHILD">
<xq:identifier>book</xq:identifier>
</xq:step>
<xq:step axis="CHILD">
<xq:identifier>title</xq:identifier>
</xq:step>
</xq:forAssignment>
<xq:return>
<xq:variable>$b</xq:variable>
</xq:return>
</xq:flwr>
</xq:query>
Tags are given as literals
XQuery expression which is evaluated to become the contents of the element is enclosed in curly braces
The contents can also contain literal text outside the braces
List titles of all books in a bib
element.
Put each title in a book
element.
<bib>
{
FOR $t IN document("bib.xml")/bib/book/title
RETURN
<book>
{ $t }
</book>
}
</bib>
Adapted from XML Query Use Cases
<bib>
<book>
<title>TCP/IP Illustrated</title>
</book>
<book>
<title>Advanced Programming in the Unix Environment</title>
</book>
<book>
<title>Data on the Web</title>
</book>
<book>
<title>The Economics of Technology and Content for Digital TV</title>
</book>
</bib>
Adapted from XML Query Use Cases
List titles of books published by Addison-Wesley
<bib>
{
FOR $b IN document("bib.xml")/bib/book
WHERE $b/publisher = "Addison-Wesley"
RETURN
$b/title
}
</bib>
This WHERE
clause could be replaced by an XPath predicate:
<bib>
{
FOR $b IN document("bib.xml")/bib/book[publisher="Addison-Wesley"]
RETURN
$b/title
}
</bib>
But WHERE
clauses can combine
multiple variables from multiple documents
Adapted from XML Query Use Cases
<bib>
<title>TCP/IP Illustrated</title>
<title>Advanced Programming in the Unix Environment</title>
</bib>
Adapted from XML Query Use Cases
XQuery booleans include:
AND
OR
NOT()
List books published by Addison-Wesley after 1993:
<bib>
{
FOR $b IN document("bib.xml")/bib/book
WHERE $b/publisher = "Addison-Wesley" AND $b/@year > 1993
RETURN
$b/title
}
</bib>
Adapted from XML Query Use Cases
<bib>
<title>Advanced Programming in the Unix Environment</title>
</bib>
Adapted from XML Query Use Cases
List books published by Addison-Wesley after 1993, including their year and title:
<bib>
{
FOR $b IN document("bib.xml")/bib/book
WHERE $b/publisher = "Addison-Wesley" AND $b/@year > 1993
RETURN
<book year = { $b/@year }>
{ $b/title }
</book>
}
</bib>
This is not well-formed XML!
Adapted from XML Query Use Cases
<bib>
<book year="1992">
<title>Advanced Programming in the Unix Environment</title>
</book>
</bib>
Adapted from XML Query Use Cases
Create a list of all the title-author pairs, with each pair enclosed in
a result
element.
<results>
{
FOR $b IN document("bib.xml")/bib/book,
$t IN $b/title,
$a IN $b/author
RETURN
<result>
{ $t }
{ $a }
</result>
}
</results>
Adapted from XML Query Use Cases
<results>
<result>
<title>TCP/IP Illustrated</title>
<author><last>Stevens</last><first>W.</first></author>
</result>
<result>
<title>Advanced Programming in the Unix Environment</title>
<author><last>Stevens</last><first>W.</first></author>
</result>
<result>
<title>Data on the Web</title>
<author><last>Abiteboul</last><first>Serge</first></author>
</result>
<result>
<title> Data on the Web</title>
<author><last>Buneman</last><first>Peter</first></author>
</result>
<result>
<title>Data on the Web</title>
<author><last>Suciu</last><first>Dan</first></author>
</result>
</results>
Adapted from XML Query Use Cases
For each book in the bibliography, list the title and authors, grouped inside
a result
element.
<results>
{
FOR $b IN document("bib.xml")/bib/book
RETURN
<result>
{ $b/title }
{
FOR $a IN $b/author
RETURN $a
}
</result>
}
</results>
Adapted from XML Query Use Cases
<?xml version="1.0"?>
<results xmlns:ino="http://namespaces.softwareag.com/tamino/response2" xmlns:xql="http://metalab.unc.edu/xql/">
<result>
<title>TCP/IP Illustrated</title>
<author>
<last>Stevens</last>
<first>W.</first>
</author>
</result>
<result>
<title>Advanced Programming in the Unix Environment</title>
<author>
<last>Stevens</last>
<first>W.</first>
</author>
</result>
<result>
<title>Data on the Web</title>
<author>
<last>Abiteboul</last>
<first>Serge</first>
</author>
<author>
<last>Buneman</last>
<first>Peter</first>
</author>
<author>
<last>Suciu</last>
<first>Dan</first>
</author>
</result>
<result>
<title>The Economics of Technology and Content for Digital TV</title>
</result>
</results>
Adapted from XML Query Use Cases
For each author in the bibliography, list the author's name and the titles of
all books by that author, grouped inside a result
element.
<results>
{
FOR $a IN distinct-values(document("bib.xml")//author)
RETURN
<result>
{ $a }
{ FOR $b IN document("bib.xml")/bib/book[author=$a]
RETURN $b/title
}
</result>
}
</results>
Adapted from XML Query Use Cases
<results>
<result>
<author><last>Stevens</last><first>W.</first></author>
<title>TCP/IP Illustrated</title>
<title>Advanced Programming in the Unix Environment</title>
</result>
<result>
<author><last>Abiteboul</last><first>Serge</first></author>
<title>Data on the Web</title>
</result>
<result>
<author><last>Buneman</last><first>Peter</first></author>
<title>Data on the Web</title>
</result>
<result>
<author><last>Suciu</last><first>Dan</first></author>
<title>Data on the Web</title>
</result>
</results>
Adapted from XML Query Use Cases
List the titles and years of all books published by Addison-Wesley after 1991, in alphabetic order.
<bib>
{
FOR $b IN document("bib.xml")//book
[publisher = "Addison-Wesley" AND @year > "1991"]
RETURN
<book>
{ $b/@year } { $b/title }
</book> SORTBY (title)
}
</bib>
Adapted from XML Query Use Cases
<bib>
<book year="1992">
<title>Advanced Programming in the Unix Environment</title>
</book>
<book year="1994">
<title>TCP/IP Illustrated</title>
</book>
</bib>
Adapted from XML Query Use Cases
Find books in which some element has a tag ending in "or" and the same element contains the string "Suciu" (at any level of nesting). For each such book, return the title and the qualifying element.
<result>
FOR $b IN document("bib.xml")//book,
$e IN $b/*[contains(string(.), "Suciu")]
WHERE ends_with(name($e), "or")
RETURN
<book>
{ $b/title} { $e }
</book>
</result>
Not supported by Quip yet
Adapted from XML Query Use Cases
<result>
<book>
<title> Data on the Web </title>
<author> <last> Suciu </last> <first> Dan </first> </author>
</book>
</result>
Adapted from XML Query Use Cases
Sample data at "reviews.xml":
<reviews> <entry> <title>Data on the Web</title> <price>34.95</price> <review> A very good discussion of semi-structured database systems and XML. </review> </entry> <entry> <title>Advanced Programming in the Unix Environment</title> <price>65.95</price> <review> A clear and detailed discussion of UNIX programming. </review> </entry> <entry> <title>TCP/IP Illustrated</title> <price>65.95</price> <review> One of the best books on TCP/IP. </review> </entry> </reviews>
Adapted from XML Query Use Cases
<!ELEMENT reviews (entry*)> <!ELEMENT entry (title, price, review)> <!ELEMENT title (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ELEMENT review (#PCDATA)>
For each book found in both bib.xml and reveiws.xml, list the title of the book and its price from each source.
<books-with-prices>
{
FOR $b IN document("bib.xml")//book,
$a IN document("reviews.xml")//entry
WHERE $b/title = $a/title
RETURN
<book-with-prices>
{ $b/title },
<price-amazon> { $a/price/text() } </price-amazon>
<price-bn> { $b/price/text() } </price-bn>
</book-with-prices>
}
</books-with-prices>
Adapted from XML Query Use Cases
<books-with-prices>
<book-with-prices>
<title>TCP/IP Illustrated</title>
<price-amazon>65.95</price-amazon>
<price-bn>65.95</price-bn>
</book-with-prices>
<book-with-prices>
<title>Advanced Programming in the Unix Environment</title>
<price-amazon>65.95</price-amazon>
<price-bn>65.95</price-bn>
</book-with-prices>
<book-with-prices>
<title>Data on the Web</title>
<price-amazon>34.95</price-amazon>
<price-bn>39.95</price-bn>
</book-with-prices>
</books-with-prices>
Adapted from XML Query Use Cases
The next query also uses an input document named "prices.xml":
<prices> <book> <title>Advanced Programming in the Unix Environment</title> <source>www.amazon.com</source> <price>65.95</price> </book> <book> <title>Advanced Programming in the Unix Environment </title> <source>www.bn.com</source> <price>65.95</price> </book> <book> <title>TCP/IP Illustrated </title> <source>www.amazon.com</source> <price>65.95</price> </book> <book> <title>TCP/IP Illustrated </title> <source>www.bn.com</source> <price>65.95</price> </book> <book> <title>Data on the Web</title> <source>www.amazon.com</source> <price>34.95</price> </book> <book> <title>Data on the Web</title> <source>www.bn.com</source> <price>39.95</price> </book> </prices>
Adapted from XML Query Use Cases
In the document "prices.xml", find the minimum price for each book, in the
form of a minprice
element with the book title as its
title
attribute.
<results>
{
FOR $t IN distinct(document("prices.xml")/book/title)
LET $p := $doc/book[title = $t]/price
RETURN
<minprice title = { $t/text() } >
{ min($p) }
</minprice>
}
</results>
Adapted from XML Query Use Cases
<results>
<minprice title="Advanced Programming in the Unix Environment"> 65.95 </minprice>
<minprice title="TCP/IP Illustrated"> 65.95 </minprice>
<minprice title="Data on the Web"> 34.95 </minprice>
</results>
Adapted from XML Query Use Cases
For each book with an author, return a
book
with its title and authors. For
each book with an editor, return a
reference
with the book title and the
editor's affiliation.
<bib>
{
FOR $b IN document("bib.xml")//book[author]
RETURN
<book>
{ $b/title }
{ $b/author }
</book>,
FOR $b IN document("bib.xml")//book[editor]
RETURN
<reference>
{ $b/title }
<org> { $b/editor/affiliation/text() } </org>
</reference>
}
</bib>
Adapted from XML Query Use Cases
<bib>
<book>
<title>TCP/IP Illustrated</title>
<author><last> Stevens </last> <first> W.</first></author>
</book>
<book>
<title>Advanced Programming in the Unix Environment</title>
<author><last>Stevens</last><first>W.</first></author>
</book>
<book>
<title>Data on the Web</title>
<author><last>Abiteboul</last><first>Serge</first></author>
<author><last>Buneman</last><first>Peter</first></author>
<author><last>Suciu</last><first>Dan</first></author>
</book>
<reference>
<title>The Economics of Technology and Content for Digital TV</title>
<org>CITI</org>
</reference>
</bib>
Adapted from XML Query Use Cases
Quilt: http://www.almaden.ibm.com/cs/people/chamberlin/quilt.html
Kweelt: http://db.cis.upenn.edu/Kweelt/
Ipedo: http://www.ipedo.com/
XSLT is document-driven; XQuery is program driven
XSLT is functional; XQuery is imperative
XSLT is written in XML; XQuery is not
An assertion (unproven): XSLT 2.0 can do everything XQuery can do
This presentation: http://www.cafeconleche.org/slides/sd2002west/xslt2/
XSLT 2.0 Working Draft: http://www.w3.org/TR/xslt20/
XPath 2.0 Requirements: http://www.w3.org/TR/2001/WD-xpath20req-20010214
XSLT 2.0 Requirements: http://www.w3.org/TR/2001/WD-xslt20req-20010214
XQuery: A Query Language for XML: http://www.w3.org/TR/xquery/
XML Query Requirements: http://www.w3.org/TR/xmlquery-req
XML Query Use Cases: http://www.w3.org/TR/xmlquery-use-cases
XML Query Data Model: http://www.w3.org/TR/query-datamodel/
The XML Query Algebra: http://www.w3.org/TR/query-algebra/
XML Syntax for XQuery 1.0 (XQueryX): http://www.w3.org/TR/xqueryx
XQuery 1.0 and XPath 2.0 Functions and Operators Version 1.0: http://www.w3.org/TR/xquery-operators/