Как выбрать тип возврата 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"/>
Другие вопросы по тегам