Динамические переменные в XSLT - PullRequest
5 голосов
/ 15 января 2009

Я передаю несколько пар ключ-значение в качестве параметров XSL (дата -> «20 января», автор -> «Доминик Роджер», ...).

На них есть ссылки в каком-то XML-файле, который я анализирую - XML ​​выглядит следующим образом:

<element datasource="date" />

В настоящее время я не могу понять, как получить 20 января из них, кроме как с ужасным <xsl:choose> заявлением:

<xsl:template match="element">
  <xsl:choose>
    <xsl:when test="@datasource = 'author'">
      <xsl:value-of select="$author" />
    </xsl:when>
    <xsl:when test="@datasource = 'date'">
      <xsl:value-of select="$date" />
    </xsl:when> 
    ...
  </xsl:choose>
</xsl:template>

Я бы хотел использовать что-то вроде:

<xsl:template match="element">
  <xsl:value-of select="${@datasource}" />
</xsl:template>

Но я подозреваю, что это невозможно. Я открываю использование внешних вызовов функций, но хочу избежать перечисления всех возможных ключей карты в моем XSL. Есть идеи?

Спасибо

Дом

Ответы [ 3 ]

2 голосов
/ 15 января 2009

Вот одно из возможных решений , однако я бы рекомендовал сгруппировать все параметры в отдельный XML-файл и получить к ним доступ с помощью функции document():

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 exclude-result-prefixes="ext"
 >
 <xsl:output method="text"/>

 <xsl:param name="date" select="'01-15-2009'"/>
 <xsl:param name="author" select="'Dominic Rodger'"/>
 <xsl:param name="place" select="'Hawaii'"/>
 <xsl:param name="time" select="'midnight'"/>

 <xsl:variable name="vrtfParams">
   <date><xsl:value-of select="$date"/></date>
   <author><xsl:value-of select="$author"/></author>
   <place><xsl:value-of select="$place"/></place>
   <time><xsl:value-of select="$time"/></time>
 </xsl:variable>

 <xsl:variable name="vParams" select="ext:node-set($vrtfParams)"/>

    <xsl:template match="element">
      <xsl:value-of select=
       "concat('&#xA;', @datasource, ' = ',
               $vParams/*[name() = current()/@datasource]
               )"
       />
    </xsl:template>
</xsl:stylesheet>

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

<data>
  <element datasource="date" />
  <element datasource="place" />
</data>

получен правильный результат :

дата = 01-15-2009

место = Гавайи

Обратите внимание на использование функции xxx:node-set() ( EXSLT one используется здесь) для преобразования RTF ( Фрагмент дерева результатов ) в обычный XML-документ (временное дерево).

0 голосов
/ 19 января 2009

Если ваш @datasource всегда совпадает с именем параметра, вы можете попробовать функцию «оценить». Примечание: этот код не проверен.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:exslt-dynamic="http://exslt.org/dynamic"
>

<xsl:param name="date"/>

<xsl:template match="element">
  <xsl:value-of select="exslt-dynamic:evaluate('$' + @datasource)"/>
</xsl:template>

</xsl:stylesheet>
0 голосов
/ 15 января 2009

Как насчет

<xsl:template match="date-element">
  <xsl:text>${date}</xsl:text>
</xsl:template>

т.е. вместо использования атрибута сопоставляйте, используя разные имена элементов.

Если вы не можете изменить исходный XML, пропустите его через небольшой XSLT, который преобразует атрибуты в правильные имена элементов.

Другим решением было бы поместить элементы xsl: param в другой документ XML (или попытаться снова заставить сам шаблон XSLT читать себя). Затем вы можете использовать xsl: key и key () для ссылки на них.

[EDIT] Заменено xsl: value-of на xsl: text. У меня нет под рукой утилиты XSLT, поэтому я не могу это проверить. Пожалуйста, оставьте комментарий, если это не сработает.

...