Как выбрать тип возврата xpath?
У меня есть запрос xpath:
<xsl:variable name="fbids">
<xsl:sequence select="
feature_relationship[type_id/cvterm[name='molec_deletes' or name='deletes']]
/object_id/feature/feature_synonym/synonym_id/synonym/synonym_sgml"/>
</xsl:variable>
Этот запрос не возвращает последовательность совпадающих узлов как саму последовательность, он возвращает их как дочерние элементы одного #documentfragment. Даже если ни один элемент не удовлетворяет этому запросу, $fbids по-прежнему устанавливается в пустой #documentfragment.
Это испортило мой код, тогда как следующий цикл, вместо того, чтобы повторяться один раз для соответствующего элемента, запускается один раз для #documentfragment и все. Как я могу заставить это вернуть хороший элемент ()* тип?
Спасибо!
2 ответа
<xsl:variable name="fbids"> <xsl:sequence select=" feature_relationship[type_id/cvterm[name='molec_deletes' or name='deletes']] /object_id/feature/feature_synonym/synonym_id/synonym/synonym_sgml"/> </xsl:variable>
Этот запрос не возвращает последовательность совпадающих узлов как саму последовательность, он возвращает их как дочерние элементы одного #documentfragment.
Да, потому что в теле переменной есть последовательность и тип переменной не указан. Тип по умолчанию в таком случае: document-node()
,
Решение:
Укажите переменную без тела и укажите выражение XPath в select
атрибут xsl:variable
:
<xsl:variable name="fbids" select="
feature_relationship[type_id/cvterm[name='molec_deletes' or name='deletes']]
/object_id/feature/feature_synonym/synonym_id/synonym/synonym_sgml"/>
По-прежнему рекомендуется указывать требуемый тип переменной с помощью as
приписывать.
Полный ответ также должен охватывать случай, когда значение переменной (последовательность элементов) динамически создается внутри ее тела.
Опять же, указание типа переменной является ключом к решению.
Вот небольшой и полный пример:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:variable name="vMapped" as="element()*">
<xsl:for-each select="num">
<num><xsl:value-of select=".*2"/></num>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="$vMapped">
<xsl:sequence select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к следующему документу XML:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
переменная с именем $vMapped
получает свое динамически созданное значение внутри своего тела. Остальная часть кода успешно использует эту переменную как последовательность элементов - каждый из элементов в этой последовательности доступен и скопирован в выходные данные:
<num>2</num>
<num>4</num>
<num>6</num>
<num>8</num>
<num>10</num>
<num>12</num>
<num>14</num>
<num>16</num>
<num>18</num>
<num>20</num>
Тип по умолчанию для переменной в XSLT 2.0 - это фрагмент документа. Если вы хотите, чтобы это была последовательность элементов, то добавьте as
атрибут и укажите тип последовательности. Вы также можете использовать select
атрибут, а не вложенный элемент последовательности:
<xsl:variable name="fbids" as="element()*" select="
feature_relationship[type_id/cvterm[name='molec_deletes' or name='deletes']]
/object_id/feature/feature_synonym/synonym_id/synonym/synonym_sgml"/>