Подтвердить что ты не робот

Создать набор узлов и передать в качестве параметра

Используя XSLT 1.0, я пытаюсь по существу создать небольшой набор node, а затем передать его как параметр шаблону, что-то вроде следующего:

<xsl:call-template name="widget">
  <xsl:with-param name="flags">
    <items>
      <item>widget.recent-posts.trim-length=100</item>
      <item>widget.recent-posts.how-many=3</item>
      <item>widget.recent-posts.show-excerpt</item>
    </items>
  </xsl:with-param>
</xsl:call-template>

Идея заключается в том, что изнутри шаблона widget я мог бы написать что-то вроде:

<xsl:value-of select="$flags/item[1]" />

Очевидно, что я получаю ошибки компиляции. Как я могу достичь такого рода вещей?

4b9b3361

Ответ 1

В XSLT 1.0 существует способ (нестандартный) динамически создавать временные деревья и оценивать выражения XPath на них , однако для этого требуется использовать функцию xxx:node-set().

Каждый раз, когда узлы динамически создаются внутри тела xsl:variable или xsl:param, типом xsl:variable/xsl:param является RTF (фрагмент дерева результатов) и W3 XSLT 1.0 Spec. полностью ограничивает вид выражений XPath, которые можно оценить с помощью RTF.

В качестве обходного решения почти каждый поставщик XSLT 1.0 имеет собственную функцию xxx:node-set() extension, которая принимает RTF и создает из нее обычный node.

Пространство имен, к которому привязан префикс xxx (или любой другой префикс), для разных поставщиков отличается. Для MSXML и двух процессоров .NET XSLT это: "urn:schemas-microsoft-com:xslt". Библиотека EXSLT использует пространство имен: "http://exslt.org/common". Это пространство имен EXSLT реализовано на многих процессорах XSLT 1.0, и рекомендуется использовать расширение xxx:node-set(), если это возможно.

Вот краткий пример:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:ext="http://exslt.org/common"
  exclude-result-prefixes="ext msxsl"
 >
 <xsl:template match="/">
  <xsl:variable name="vTempRTF">
   <a>
    <b/>
   </a>
  </xsl:variable>

  <xsl:copy-of select="ext:node-set($vTempRTF)/a/*"/>
 </xsl:template>
</xsl:stylesheet>

Ответ 2

Ну, мне удалось обойти это следующим образом:

Сначала добавьте собственное пространство имен в таблицу стилей, например. xmlns:myns="http://my.ns.com"

Затем определите набор узлов в верхней части таблицы стилей:

<myns:recent-posts-flags>
    <item>widget.recent-posts.trim-length=100</item>
    <item>widget.recent-posts.how-many=3</item>
    <item>widget.recent-posts.show-excerpt</item>
</myns:recent-posts-flags>

Затем сделайте следующее:

<xsl:call-template name="widget">
    <xsl:with-param name="flags" select="document('')/*/myns:recent-posts-flags" />
</xsl:call-template>

Это работает, но мне все же было бы идеально определить node -set внутри самого тега <xsl:with-param>, как в первом примере, который я дал. Кто-нибудь считает, что это возможно?