我正在尝试使用括号来覆盖xslt中xpath表达式中的默认运算符优先级而没有运气。例如:
<?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不会编译此返回:
意外的标记'(表达式中的'。' - &gt;(&lt; - X | Y | Z)/ AABBCC
意外的标记'('在表达式中。 - &gt;(&lt;-book / author)[last()]
然而第二个例子来自MSDN:
http://msdn.microsoft.com/en-us/library/ms256086.aspx
许多参考文献都说你可以这样使用括号:
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
这是一个xpath 1.0 vs 2.0的事情......还是还有其他我缺少的东西?如果它是一个xpath 2.0的东西,是否有一个很好的xpath 1.0方法来做同样的事情?
答案 0 :(得分:11)
请参阅@ Martin关于关键点的答案:有效的模式只是有效 XPath表达式的子集。 (这是关于XSLT的事情,我花了很长时间才意识到。)
至于有效的替代方案:
//(X|Y|Z)/AABBCC
是XPath 2.0中的有效表达式,但不是1.0,因为括号不能在//
轴之后立即开始。但是在1.0中,
(//X|//Y|//Z)/AABBCC
是一个有效的替代表达式(但仍然不是有效的模式)。一个有效但有点尴尬的模式将是
*[contains('X Y Z', local-name())]/AABBCC
或
*[self::X | self::Y | self::Z]/AABBCC
至于
(book/author)[last()]
有效的模式将是
(book/author)[not(following::author[parent::book])]
(但当然
(book/author)[not(following::book/author)]
不等同,因为它会匹配上一个<author>
的所有 <book>
个孩子。)
答案 1 :(得分:9)
您必须了解match
的{{1}}属性不允许任何XPath表达式,而只允许所谓的模式:https://www.w3.org/TR/1999/REC-xslt-19991116#patterns,XPath表达式的子集。
因此虽然xsl:template
是一个语法正确的XPath 1.0表达式,但我不认为它是一个语法正确的XSLT 1.0模式,不允许使用括号。
我认为(book/author)[last()]
不是允许的XPath 1.0表达式(当然也不是模式),但//(X|Y|Z)/AABBCC
应该这样做。