2011-05-26 74 views
10

Estoy tratando de usar paréntesis para anular la precedencia predeterminada del operador en una expresión xpath dentro de un xslt sin suerte. Por ejemplo:usando paréntesis en 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 no se compilará esta volviendo:.

símbolo inesperado '(' en la expresión // -> (< - X | Y | Z)/AABBCC .

símbolo inesperado '(' en la expresión -> (< - libro/autor) [last()]

Sin embargo, el segundo ejemplo es de MSDN:

http://msdn.microsoft.com/en-us/library/ms256086.aspx

y numerosas referencias dicen que se puede utilizar paréntesis de esta manera:

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

Es éste un XPath 1.0 vs 2.0 cosa ... o hay algo más que me estoy perdiendo? Si se trata de algo de xpath 2.0, ¿hay una buena forma de hacer xpath 1.0 para hacer lo mismo?

Respuesta

9

Tiene que entender que un atributo match de xsl:template no permite ninguna expresión XPath sino solo los llamados patrones: http://www.w3.org/TR/xslt#patterns, un subconjunto de expresiones XPath.

Así que mientras (book/author)[last()] es una expresión sintácticamente correcta de XPath 1.0, no creo que sea un patrón XSLT 1.0 sintácticamente correcto, los paréntesis no están permitidos.

No creo que //(X|Y|Z)/AABBCC sea una expresión permitida de XPath 1.0 (ni un patrón por supuesto) pero match="X/AABBCC | Y/AABBCC | Z/AABBCC" debería hacer. respuesta

+0

Gracias a Martin y Lars ... Ahora entiendo – user109078

10

Ver @ de Martin como el punto clave: que los patrones válidos son sólo un subconjunto de válidos expresiones XPath. (Esto es algo sobre XSLT que me tomó mucho tiempo para darse cuenta.)

En cuanto a alternativas válidas:

//(X|Y|Z)/AABBCC 

es una expresión válida en XPath 2.0, pero no en 1.0, debido a que los paréntesis no puede comenzar inmediatamente después del eje //. Pero en 1.0,

(//X|//Y|//Z)/AABBCC 

es una expresión alternativa válida (pero aún no es un patrón válido).A válido pero algo torpe patrón sería

*[contains('X Y Z', local-name())]/AABBCC 

o

*[self::X | self::Y | self::Z]/AABBCC 

cuanto a

(book/author)[last()] 

un patrón válido sería

(book/author)[not(following::author[parent::book])] 

(Pero, por supuesto

(book/author)[not(following::book/author)] 

no sería equivalente, ya que coincidiría todos<author> hijos de la última <book> que tenía alguna.)

Cuestiones relacionadas