использование скобок в xpath / xslt - PullRequest
11 голосов
/ 26 мая 2011

Я пытаюсь использовать скобки, чтобы переопределить приоритет оператора по умолчанию в выражении 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 </p>

Неожиданный токен '(' в выражении. -> (<- книга / автор) [last ()] </p>

И все же второй пример взят из 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 способ сделать то же самое?

Ответы [ 2 ]

11 голосов
/ 26 мая 2011

См. Ответ @ 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>, которые имели какие-либо.)

9 голосов
/ 26 мая 2011

Вы должны понимать, что атрибут match для xsl:template не допускает никаких выражений 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" должно подойти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...