Почему мои переменные XSLT не заменяют свои значения?
-
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
'sselect
атрибут уже принимает выражение как контент. Вопрос:Почему вы не можете использовать
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"/>
?