Почему мои переменные XSLT не подставляют свои значения? - PullRequest
5 голосов
/ 11 марта 2009

Я пытаюсь использовать переменные 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' моего элемента верхнего уровня 'query'.

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

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

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

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

так что значение не было подставлено, как я ожидал.

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


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

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

Ответы [ 6 ]

12 голосов
/ 14 декабря 2011

Здесь есть два вопроса, которые кажутся одинаковыми, но слегка различаются: 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>

Несколько прощальных замечаний по AVT и value-of:

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

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

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

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

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

12 голосов
/ 11 марта 2009

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

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

вместо:

{$config}
6 голосов
/ 11 марта 2009

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

3 голосов
/ 11 марта 2009

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

1 голос
/ 13 мая 2014

@ lwburk отвечает отлично (+1), но последний вопрос / ответ точен только для XSLT 1.0 и 2.0. В версии 3.0 вы можете использовать TVT ( шаблон текстовых значений ; аналогично 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.

0 голосов
/ 11 марта 2009

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

...