Por que minhas variáveis XSLT não estão substituindo seus valores?
-
10-07-2019 - |
Pergunta
Estou tentando usar variáveis XSLT e não tendo muito sucesso, espero estar apenas fazendo algo idiota.
Eu tenho o seguinte trecho de código:
<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>
então espero que haja uma variável 'config' definida como o valor do atributo 'config' do meu elemento de nível superior 'query'.
Em seguida, tento usar a variável posteriormente em minha folha de estilo, por exemplo:
<a href="localhost/test?go">
{$config}
</a>
mas a saída que vejo no meu documento HTML de saída é:
<a href="localhost/test?go">
{$config}
</a>
então o valor não foi substituído como eu esperava.
Acho que este é o caso mais simples que poderia existir, então estou fazendo algo estúpido!Por favor ajude, obrigado!
ATUALIZAÇÃO, obrigado a todos que responderam, entendi mal os diferentes contextos de estar trabalhando em um atributo ou fora dele.Resolvi meu problema muito bem!
Se pudesse, aceitaria duas respostas, a que tenho e a de @Aaron Digulla, que explicava a coisa dos atributos.
Solução
Na sua folha de estilo você deve usar:
<xsl:value-of select="$config"/>
em vez de:
{$config}
Outras dicas
Há duas questões aqui que parecem iguais, mas que são sutilmente diferentes:1) Como faço referência a uma variável pelo nome?2) Onde posso referenciar uma variável pelo nome?
Primeiro, as variáveis são sempre referenciadas usando o $varname
sintaxe.Em segundo lugar, isso pode ser feito em qualquer lugar uma expressão é permitida.É a segunda parte que parece confundir.Para começar, o valor de um elemento ou atributo será, por padrão, exibido literalmente, portanto, nenhuma variável é realmente referenciada no exemplo a seguir:
<element attr="$test">$test or {$test}</element>
A saída corresponderá literalmente ao que foi digitado.
Para gerar o valor de uma variável, precisamos referenciá-la onde uma expressão for permitida.No conteúdo do elemento, usamos xsl:value-of
;em atributos que são tratados como um Modelo de valor de atributo (por exemplo.os atributos de um elemento de resultado literal), as expressões são delimitadas por chaves {}
.Suponha a seguinte declaração:
<xsl:variable name="test" select="'value'"/>
... então o seguinte:
<element attr="{$test}"><xsl:value-of select="$test"/></element>
...resulta em:
<element attr="value">value</element>
Algumas notas de despedida sobre AVTs e value-of
:
- Em ambos os casos a variável foi referenciada como
$test
.Os colchetes em um AVT não fazem parte da referência da variável;eles são delimitadores de expressão. - Em ambos os casos, a expressão não precisa conter uma referência a uma variável;qualquer expressão XPath teria sido permitida.
- Nem todos os atributos em um documento XSLT são tratados como modelos de valores de atributos.Por exemplo, observe que
xsl:value
deselect
atributo já aceita uma expressão como conteúdo. Pergunta:Por que você não pode usar
value-of
em um atributo, como este?<element attr="<xsl:value-of select="$test"/>"/>
Responder:Porque os documentos XSLT devem conter XML bem formado (e não é).
Pergunta:Por que você não pode usar
{$varname}
no conteúdo do elemento?Resposta simplista:porque os criadores do XSLT não o projetaram dessa forma.
{$config}
funciona apenas em atributos de elementos XSLT.(Observação:dólar dentro da chave porque a expressão XPath completa deve estar entre chaves)
Usar <xsl:value-of select="$config"/>
em vez de {$config}
.
A resposta de @lwburk é ótima (+1), mas a última pergunta/resposta só é precisa para XSLT 1.0 e 2.0.No 3.0 você pode usar um TVT (Modelo de valor de texto;semelhante ao AVT (modelo de valor de atributo) mencionado na resposta de @lwburk).
Para usar um TVT, adicione o atributo padrão xsl:expand-text="yes"
ao elemento.Isso fará com que o processador trate os nós de texto descendentes desse elemento como um TVT.
Exemplo:
XSLT3.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>
Saída (usando qualquer XML bem formado como entrada)
<result>This is Dan's result: BAM!</result>
Observação:Testado usando Saxon-PE 9.5.
Porque você precisa usar <xsl:value-of select="config"/>
?