在xpath / xslt中使用括号

问题描述

| 我正在尝试使用括号在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个子元素。)