переменная странность xslt - PullRequest
0 голосов
/ 18 декабря 2011

Кто-нибудь может мне это объяснить?(используя последнюю версию libxslt):

 <a><xsl:copy-of select="(@attrib|exsl:node-set(0))"/></a>
 <b><xsl:copy-of select="(@attrib|exsl:node-set(0))[position()=1]"/></b>

 <x><xsl:copy-of select="(@attrib|exsl:node-set(0))[1]"/></x>
 <xsl:variable name="value" select="@attrib"/>
 <y><xsl:copy-of select="($value|exsl:node-set(0))[1]"/></y>

Результат (для @attrib = 1 в текущем узле):

 <a attrib="1">0</a>
 <b attrib="1"/>

 <x>0</x>
 <y attrib="1"/>

<a> и <b> показывают ожидаемое поведение.
<x> ИМХО неверно.
Но почему помещает @attrib в переменную, "исправляет" это для <y>?

Кстати: все правильно, когда @attrib isнетИспользуемая здесь копия предназначена для отладки;первоначальное использование преобразует результат XPath в число, а отсутствующий атрибут не должен приводить к NaN, а к определенному значению по умолчанию.

Ответы [ 2 ]

1 голос
/ 18 декабря 2011

Из комментария ОП:

Хорошо, это означает, что мой единственный вариант использует <xsl:choose> ..., правильно?

В то время, как выпопытка привести к непредсказуемым результатам по причинам, объясненным @Michael Kay и мной в моих комментариях, все еще есть способы сделать то, что вы хотите (создать либо значение атрибута attrib, либо значение по умолчанию (0) :

concat(@attrib,
       substring(0, 2 -not(@attrib))
       )

Создает значение атрибута attrib (если этот атрибут присутствует) или (если нет) значение по умолчанию 0.

Полное решение XSLT :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="x">
  <xsl:value-of select=
   "concat(@attrib,
           substring('0', 2 -not(@attrib))
           )"/>

==========
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к следующему документу XML :

<t>
 <x attrib="abc"/>
 <x/>
</t>

желаемый, правильный результат выдается :

 abc

==========

 0

==========
1 голос
/ 18 декабря 2011

Эта версия exsl: node-set () предположительно создает узел, который находится в дереве, отличном от узла @attrib.Когда два узла находятся в разных деревьях, зависит от реализации, какой из них стоит первым в порядке документа.Конструкция (X|Y)[position()=1] (или эквивалентно (X|Y)[1]) выбирает, какой из X и Y идет первым в порядке документа.Поэтому, по сути, непредсказуемо, выбирает ли он X или Y.

...