I'm trying to use parentheses to override default operator precedence in an xpath expression within an xslt with no luck. For example:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
version="1.0">
<xsl:output encoding="utf-8" standalone="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!--these should work but don't-->
<xsl:template match="//(X|Y|Z)/AABBCC"/>
<xsl:template match="(book/author)[last()]"/>
</xsl:stylesheet>
Visual Studio 2010 won't compile this returning:
Unexpected token '(' in the expression. // -->(<-- X|Y|Z)/AABBCC
Unexpected token '(' in the expression. -->(<-- book/author)[last()]
Yet the second example is from MSDN:
http://msdn.microsoft.com/en-us/library/ms256086.aspx
and numerous references say you can use parentheses in this way:
http://saxon.sourceforge.net/saxon6.5.3/expressions.html
http://www.stylusstudio.com/xsllist/200207/post90450.html
http://www.mulberrytech.com/quickref/XSLT_1quickref-v2.pdf
Is this an xpath 1.0 vs 2.0 thing...or is there something else i'm missing? If it's an xpath 2.0 thing, is there a nice xpath 1.0 way to do the same thing?
In XPath, the square-bracket notation ( [] ) normally associated with indexing is extended to specify selection criteria. So the expression LIST[@type="unordered"] selects all LIST elements whose type value is unordered . Similar expressions exist for elements.
XPath is a major element in the XSLT standard. XPath can be used to navigate through elements and attributes in an XML document.
XSL (Extensible Stylesheet Language), formerly called Extensible Style Language, is a language for creating a style sheet that describes how data sent over the Web using the Extensible Markup Language (XML) is to be presented to the user.
See @Martin's answer for the key point: that valid patterns are only a subset of valid XPath expressions. In other words, there are many XPath expressions that cannot be used as patterns. (This is something about XSLT that it took me a long time to realize.)
As for valid alternatives:
//(X|Y|Z)/AABBCC
is a valid expression in XPath 2.0, but not in 1.0, because the parentheses cannot begin immediately after the //
axis. But in 1.0,
(//X|//Y|//Z)/AABBCC
is a valid alternative expression (but still not a valid pattern). A valid but somewhat awkward pattern would be
*[contains('X Y Z', local-name())]/AABBCC
or
*[self::X | self::Y | self::Z]/AABBCC
As for
(book/author)[last()]
a valid pattern would be
(book/author)[not(following::author[parent::book])]
(But of course
(book/author)[not(following::book/author)]
would not be equivalent, because it would match all <author>
children of the last <book>
that had any.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With