问题描述
|
我正在尝试使用括号在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不会编译以下返回:
表达式中的意外标记\'(\'。//->(<-X | Y | Z)/ AABBCC
表达式中的意外标记\'(\'。->(<-书/作者)[last()]
第二个示例来自MSDN:
http://msdn.microsoft.com/en-us/library/ms256086.aspx
许多参考文献都说您可以通过以下方式使用括号:
http://saxon@R_404[email protected]/saxon6.5.3/expressions.html
http://www.stylu@R_404_6455@udio.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方式可以做同样的事情?
解决方法
您必须了解
xsl:template
的match
属性不允许任何XPath表达式,而仅允许所谓的模式:https://www.w3.org/TR/1999/REC-xslt-19991116#patterns,XPath的子集表达式。
因此,尽管(book/author)[last()]
是语法上正确的XPath 1.0表达式,但我认为这不是语法上正确的XSLT 1.0模式,但不允许使用括号。
我不认为//(X|Y|Z)/AABBCC
是允许的XPath 1.0表达式(当然也不是模式),但match=\"X/AABBCC | Y/AABBCC | Z/AABBCC\"
应该是。
,有关关键点,请参见@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)]
是不等价的,因为它将匹配最后一个有15个子元素的所有14个子元素。)