Почему мои переменные XSLT не заменяют свои значения?

StackOverflow https://stackoverflow.com/questions/634295

  •  10-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь использовать переменные XSLT, но безуспешно. Надеюсь, я просто делаю что-то глупое.

У меня есть следующий фрагмент кода:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xalan="http://xml.apache.org/xslt"
  version="1.0">

    <xsl:template match="/">
      <xsl:variable name="config" select="query/@config"></xsl:variable>

поэтому я ожидаю, что для переменной «config» будет установлено значение атрибута «config» моего запроса элемента верхнего уровня.

Затем я пытаюсь использовать эту переменную позже в своей таблице стилей, например:

<a href="localhost/test?go">
    {$config}
</a>

но результат, который я вижу в своем выходном HTML-документе:

<a href="localhost/test?go">
    {$config}
</a>

поэтому значение не было заменено, как я ожидал.

Я думаю, что это самый простой случай, который только может быть, поэтому я делаю глупость!Пожалуйста, помогите, спасибо!


ОБНОВЛЕНИЕ, спасибо всем, кто ответил, я неправильно понял разные контексты того, работал ли я в атрибуте или снаружи.Отлично разобрался с моей проблемой!

Если бы я мог, я бы принял два ответа: тот, который у меня есть, и ответ @Aaron Digulla, который объясняет атрибуты.

Это было полезно?

Решение

В вашей таблице стилей вы должны использовать:

<xsl:value-of select="$config"/>

вместо:

{$config}

Другие советы

Здесь есть два вопроса, которые кажутся одинаковыми, но слегка различаются:1) Как я ссылаюсь на переменную по имени?2) Где могу ли я ссылаться на переменную по имени?

Во-первых, на переменные всегда ссылаются с помощью $varname синтаксис.Во-вторых, это можно сделать везде, где разрешено выражение.Кажется, смущает вторая часть.Начнем с того, что значение элемента или атрибута по умолчанию будет выведено буквально, поэтому в следующем примере фактически не упоминаются никакие переменные:

<element attr="$test">$test or {$test}</element>

Вывод будет буквально соответствовать тому, что было напечатано.

Чтобы вывести значение переменной, нам нужно сослаться на нее там, где разрешено выражение.В содержимом элемента мы используем xsl:value-of;в атрибутах, которые рассматриваются как Шаблон значения атрибута (например.атрибуты буквального элемента результата), выражения ограничиваются фигурными скобками. {}.Предположим следующее объявление:

<xsl:variable name="test" select="'value'"/>

...тогда следующее:

<element attr="{$test}"><xsl:value-of select="$test"/></element>

...результат:

<element attr="value">value</element>

Несколько напутственных слов по поводу АВТ и value-of:

  • В обоих случаях переменная упоминалась как $test.Фигурные скобки в AVT не являются частью ссылки на переменную;они являются разделителями выражений.
  • В любом случае выражение не обязательно должно содержать ссылку на переменную;любое выражение XPath было бы разрешено.
  • Не все атрибуты в документе XSLT рассматриваются как шаблоны значений атрибутов.Например, обратите внимание, что xsl:value's select атрибут уже принимает выражение как контент.
  • Вопрос:Почему вы не можете использовать value-of в атрибуте, вот так?

    <element attr="<xsl:value-of select="$test"/>"/>
    

    Отвечать:Потому что документы XSLT должны содержать правильно сформированный XML (а это не так).

  • Вопрос:Почему вы не можете использовать {$varname} в содержании элемента?

    Бойкий ответ:потому что создатели XSLT не задумывали его таким образом.

{$config} работает только в атрибутах элементов XSLT.(Примечание:доллар внутри фигурных скобок, поскольку полное выражение XPath должно быть заключено в фигурные скобки)

Использовать <xsl:value-of select="$config"/> вместо {$config}.

Ответ @lwburk великолепен (+1), но последний вопрос/ответ верен только для XSLT 1.0 и 2.0.В 3.0 можно использовать ТВТ(Шаблон текстового значения;аналогично AVT (шаблону значений атрибута), упомянутому в ответе @lwburk).

Чтобы использовать TVT, добавьте стандартный атрибут xsl:expand-text="yes" к элементу.Это заставит процессор рассматривать текстовые узлы-потомки этого элемента как TVT.

Пример:

XSLT 3.0

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

    <xsl:template match="/">
        <xsl:variable name="who" select="'Dan'"/>
        <xsl:variable name="what" select="'BAM!'"/>
        <result xsl:expand-text="yes">This is {$who}'s result: {$what}</result>
    </xsl:template>

</xsl:stylesheet>

Выход (используя любой правильно сформированный XML в качестве входных данных)

<result>This is Dan's result: BAM!</result>

Примечание:Протестировано с использованием Saxon-PE 9.5.

Потому что вам нужно использовать <xsl:value-of select="config"/> ?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top