matchpatterns; avts;control structures; xpathtei.it.ox.ac.uk/talks/2008-07-xsl/xsl02.pdf · xpath...
TRANSCRIPT
Match patterns;AVTs; controlstructures;
XPath
.
.
. ..
.
.
Match patterns; AVTs; control structures; XPath
Match patterns;AVTs; controlstructures;
XPath
More complex match patterns
The match attribute of <template> can point to any part ofthe document. We can find:
/ the root of document (outside the root element)* any elementtext()name an element called ‘name’@name an attribute called ‘name’
You can join these together using ‘/’ to find a path downthrough child nodes. ‘//’ stands for multiple levels.
Match patterns;AVTs; controlstructures;
XPath
Example of context-dependent matches
Compare.
.
. ..
.
.
<xsl:template match="tei:head"> ....</xsl:template>
with.
.
. ..
.
.
<xsl:template match="tei:div/tei:head"> ...</xsl:template><xsl:template match="tei:figure/tei:head"> ....</xsl:template>
Match patterns;AVTs; controlstructures;
XPath
More esoteric examples (from RSS)
.
.
. ..
.
.
<xsl:templatematch="atom:feed/atom:entry/atom:author/atom:name"/>
.
.
. ...
.
<xsl:template match="atom:feed/atom:entry/atom:content"/>
.
.
. ..
.
.
<xsl:template match="atom:feed/atom:entry"><xsl:apply-templates select="@href"/>
</xsl:template><xsl:template match="@href"><xsl:value-of select="."/>
</xsl:template>
.
.
. ...
.
<xsl:template match="xhtml:*"/>
.
.
. ..
.
.
<xsl:template match="atom:feed//xhtml:*">…</xsl:template>
Match patterns;AVTs; controlstructures;
XPath
Priorities when templates conflict
It is possible for it to be ambiguous which template is to beused:.
.
. ..
.
.
<xsl:template match="person/name">…</xsl:template><xsl:template match="name">…</xsl:template>
when the processor meets a <name>, which template is used?
Match patterns;AVTs; controlstructures;
XPath
Solving priorities
There is a priority attribute on <template>; the higher thevalue, the more inclined the XSLT engine is to use it:.
.
. ..
.
.
<xsl:template match="name" priority="1"><xsl:apply-templates/>
</xsl:template><xsl:template match="person/name" priority="2"/>
Match patterns;AVTs; controlstructures;
XPath
Template priority generally
The more normal rule is that the most specific template wins..
.
. ..
.
.
<xsl:template match="*"><!-- ... --></xsl:template><xsl:template match="atom:*"><!-- ... --></xsl:template><xsl:template match="atom:entry"><!-- ... --></xsl:template><xsl:template match="atom:channel/atom:entry"><!-- ... --></xsl:template><xsl:template match="atom:channel/atom:entry/text()"><!-- ... --></xsl:template>
Match patterns;AVTs; controlstructures;
XPath
Pushing and pulling
XSLT stylesheets can be characterized as being of two types:push In this type of stylesheet, there is a different
template for every element, communication via<xsl:apply-templates> and the overallresult is assembled from bits in each template. It issometimes hard to visualize the final design.Common for data-oriented processing where thestructure is fixed.
pull In this type, there is a master template (usuallymatching /) with the main structure of theoutput, and specific <xsl:for-each> or<xsl:value-of> commands to grab what isneeded for each part. The templates tend to getlarge and unwieldy. Common fordocument-oriented processing where the inputdocument structure varies.
Match patterns;AVTs; controlstructures;
XPath
Attribute value template
What if we to turn.
.
. ..
.
.
<linkhref="http://www.oucs.ox.ac.uk/ltg/events/dpoh2007.xml"/>
into.
.
. ..
.
.
<ahref="http://www.oucs.ox.ac.uk/ltg/events/dpoh2007.xml"/>
? What we cannot do is.
.
. ..
.
.
<xsl:template match="link"><a href="@href"><xsl:apply-templates/>
</a></xsl:template>
because that would mean an attribute with literally the value"@href".
Match patterns;AVTs; controlstructures;
XPath
AVT example
Instead we use {} to force XSL to evaluate the expression:.
.
. ..
.
.
<xsl:template match="link"><a href="{@href}"><xsl:apply-templates/>
</a></xsl:template>
Match patterns;AVTs; controlstructures;
XPath
Feature: for-each
If we want to avoid lots of templates, we can do in-line loopingover a set of elements. So, using the student data:.
.
. ..
.
.
<xsl:template match="people"><ul><xsl:for-each select="person"><li><xsl:value-of select="name"/>
</li></xsl:for-each>
</ul></xsl:template>
contrast with.
.
. ..
.
.
<xsl:template match="people"><ul><xsl:apply-templates select="person"/>
</ul></xsl:template><xsl:template match="person"><li><xsl:value-of select="name"/>
</li></xsl:template>
Match patterns;AVTs; controlstructures;
XPath
Feature: if
We can make code conditional on a test being passed:.
.
. ..
.
.
<xsl:template match="person"><xsl:if test="title='Dr'"><li><xsl:value-of select="name"/>
</li></xsl:if>
</xsl:template>
contrast withThe@test can use any XPath facilities.
Match patterns;AVTs; controlstructures;
XPath
XPath: Operators
XPath has support for numerical, equality, relational, andboolean expressions
+ Addition 3 + 2 = 5- Subtraction 10 - 2 = 8* Multiplication 6 * 4 = 24div Division 8 div 4 = 2mod Modulus 5 mod 2 = 1= Equal @age = '74' Trueor Boolean OR @age = '74' or @age = '64' True
Match patterns;AVTs; controlstructures;
XPath
XPath: Operators (cont.)
< Less than @age < '84' True!= Not equal @age != '74' False<= Less than or equal @age <= '72' False> Greater than @age > '25' True>= Greater than or equal @age >= '72' Trueand Boolean AND @age <= '84' and @age > '70' True
Match patterns;AVTs; controlstructures;
XPath
What is XPath?
It is a syntax for accessing parts of an XML document
It uses a path structure to define XML elements
It has a library of standard functions
It is a W3C Standard
It is one of the main components of XQuery and XSLT
Match patterns;AVTs; controlstructures;
XPath
Example text
.
.
. ..
.
.
<body type="anthology"><div type="poem"><head>The SICK ROSE </head><lg type="stanza"><l n="1">O Rose thou art sick.</l><l n="2">The invisible worm,</l><l n="3">That flies in the night </l><l n="4">In the howling storm:</l>
</lg><lg type="stanza"><l n="5">Has found out thy bed </l><l n="6">Of crimson joy:</l><l n="7">And his dark secret love </l><l n="8">Does thy life destroy.</l>
</lg></div>
</body>
Match patterns;AVTs; controlstructures;
XPathXML Structure
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Really attributes (and text) are separate nodes!
Match patterns;AVTs; controlstructures;
XPath/body/div/head
body type=“anthology”
div type= “poem”
div type= “shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
XPath locates any matching nodes
Match patterns;AVTs; controlstructures;
XPath/body/div/lg ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath/body/div/lg
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath/body/div/@type ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
@ = attributes
Match patterns;AVTs; controlstructures;
XPath/body/div/@type
body type=“anthology”
div type= “poem”
div
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
type=“poem”
type=“shortpoem”
Match patterns;AVTs; controlstructures;
XPath/body/div/lg/l ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath/body/div/lg/l
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath/body/div/lg/l[@n=“2”] ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Square Brackets Filter Selection
Match patterns;AVTs; controlstructures;
XPath/body/div/lg/l[@n=“2”]
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath/body/div[@type=“poem”]/head ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath/body/div[@type=“poem”]/head
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath//lg[@type=“stanza”] ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
// = any descendant
Match patterns;AVTs; controlstructures;
XPath//lg[@type=“stanza”]
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath//div[@type=“poem”]//l ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath//div[@type=“poem”]//l
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath//l[5] ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Square brackets can also filter by counting
Match patterns;AVTs; controlstructures;
XPath//l[5]
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath//lg/../@type ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Paths are relative: .. = parent
Match patterns;AVTs; controlstructures;
XPath//lg/../@type
body type=“anthology”
div type= “poem”
div
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
type=“poem”
type=“shortpoem”
Match patterns;AVTs; controlstructures;
XPath//l[@n > 5] ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Numerical operations can be useful.
Match patterns;AVTs; controlstructures;
XPath//l[@n > 5]
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath//div[head]/lg/l[@n=“2”] ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Notice the deleted <head> !
Match patterns;AVTs; controlstructures;
XPath//div[head]/lg/l[@n=“2”]
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath//l[ancestor::div/@type=“shortpoem”] ?
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
ancestor:: is an unabbreviated axis name
Match patterns;AVTs; controlstructures;
XPath//l[ancestor::div/@type=“shortpoem”]
body type=“anthology”
div type=“poem”
div type=“shortpoem”
head
head
lg type=“stanza”
lg type=“couplet”
l n=“4”
l n=“6”
l n=“2”
l n=“3”
l n=“7”
l n=“1”
l n=“8”
l n=“5”
l n=“1”
lg type=“stanza”
l n=“2”l n=“2”
l n=“2”
Match patterns;AVTs; controlstructures;
XPath
XPath: More About Paths
A location path results in a node-set
Paths can be absolute (/div/lg[1]/l)Paths can be relative (l/../../head)Formal Syntax: (axisname::nodetest[predicate])For example:child::div[contains(head,'ROSE')]
Match patterns;AVTs; controlstructures;
XPath
XPath: Axes
ancestor:: Contains all ancestors (parent, grandparent, etc.)of the current node
ancestor-or-self:: Contains the current node plus all itsancestors (parent, grandparent, etc.)
attribute:: Contains all attributes of the current node
child:: Contains all children of the current node
descendant:: Contains all descendants (children,grandchildren, etc.) of the current node
descendant-or-self:: Contains the current node plus allits descendants (children, grandchildren, etc.)
Match patterns;AVTs; controlstructures;
XPath
XPath: Axes (2)
following:: Contains everything in the document after theclosing tag of the current node
following-sibling:: Contains all siblings after thecurrent node
parent:: Contains the parent of the current node
preceding:: Contains everything in the document that isbefore the starting tag of the current node
preceding-sibling:: Contains all siblings before thecurrent node
self:: Contains the current node
Match patterns;AVTs; controlstructures;
XPath
Axis examples
ancestor::lg = all <lg> ancestorsancestor-or-self::div = all <div> ancestors orcurrentattribute::n = n attribute of current nodechild::l = <l> elements directly under current nodedescendant::l = <l> elements anywhere undercurrent nodedescendant-or-self::div = all <div> children orcurrentfollowing-sibling::l[1] = next <l> element atthis levelpreceding-sibling::l[1] = previous <l> elementat this levelself::head = current <head> element
Match patterns;AVTs; controlstructures;
XPath
XPath: Predicates
child::lg[attribute::type='stanza']child::l[@n='4']child::div[position()=3]child::div[4]child::l[last()]child::lg[last()-1]
Match patterns;AVTs; controlstructures;
XPath
XPath: Abbreviated Syntax
nothing is the same as child::, so lg is short forchild::lg@ is the same as attribute::, so @type is short forattribute::type. is the same as self::, so ./head is short forself::node()/child::head.. is the same as parent::, so../lg is short forparent::node()/child::lg// is the same as descendant-or-self::, so div//lis short for child::div/descendant-or-self::node()/child::l