2011-05-26 67 views
10

我想用括号在xslt中重写xpath中的默认运算符优先级,但没有运气。例如:在xpath/xslt中使用圆括号

<?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 。

意外标记 '(' 在表达 - >(< - 书/作者)[最后()]

然而,第二个例子是从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方法来做同样的事情?

回答

9

您必须明白,xsl:templatematch属性不允许任何XPath表达式,而只允许所谓的模式:http://www.w3.org/TR/xslt#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"应该这样做。

+0

感谢Martin和Lars ......我现在明白 – user109078 2011-05-26 17:18:11

10

见@马丁的答案的关键点:即有效模式仅适用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)] 

不会是等价的,因为它会匹配最后<book>认为有任何的所有<author>孩子。)

相关问题