Perché le mie variabili XSLT non stanno sostituendo i loro valori?
-
10-07-2019 - |
Domanda
Sto cercando di usare le variabili XSLT e non sto avendo molto successo, spero di fare qualcosa di stupido.
Ho il seguente frammento di codice:
<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>
quindi mi aspetto che ci sia una variabile 'config' impostata sul valore dell'attributo 'config' del mio elemento di livello superiore 'query'.
Provo quindi a utilizzare la variabile più avanti nel mio foglio di stile, ad esempio:
<a href="localhost/test?go">
{$config}
</a>
ma l'output che vedo nel mio documento HTML di output è:
<*>quindi il valore non è stato sostituito come mi sarei aspettato.
Penso che questo sia praticamente il caso più semplice che ci possa essere, quindi sto facendo lo stupido! Per favore, grazie!
AGGIORNAMENTO grazie a tutti coloro che hanno risposto, ho frainteso i diversi contesti se stavo lavorando in un attributo o fuori. Risolto il mio problema!
Se potessi, accetterei due risposte, quella che ho e quelle di @Aaron Digulla, che spiegano la cosa degli attributi.
Soluzione
Nel tuo foglio di stile devi usare:
<xsl:value-of select="$config"/>
anziché:
{$config}
Altri suggerimenti
Ci sono due domande che sembrano uguali, ma che sono leggermente diverse: 1) Come faccio riferimento a una variabile per nome? 2) Dove posso fare riferimento a una variabile per nome?
Innanzitutto, alle variabili viene sempre fatto riferimento utilizzando la sintassi $varname
. In secondo luogo, ciò può essere fatto ovunque sia consentita un'espressione . È la seconda parte di questo che sembra confondere. Per cominciare, il valore di un elemento o di un attributo verrà emesso per impostazione predefinita letteralmente, quindi nessuna variabile viene effettivamente referenziata nel seguente esempio:
<element attr="$test">$test or {$test}</element>
L'output corrisponderà letteralmente a ciò che è stato digitato.
Per generare il valore di una variabile, dobbiamo fare riferimento a essa dove è consentita un'espressione. Nel contenuto dell'elemento, usiamo xsl:value-of
; negli attributi trattati come Modello valore attributo (ad es. gli attributi di un elemento di risultato letterale), le espressioni sono delimitate da parentesi graffe {}
. Supponi la seguente dichiarazione:
<xsl:variable name="test" select="'value'"/>
... quindi quanto segue:
<element attr="{$test}"><xsl:value-of select="$test"/></element>
... risulta in:
<element attr="value">value</element>
Alcune note di separazione su AVT e value-of
:
- In entrambi i casi la variabile è stata indicata come
$test
. Le parentesi graffe in un AVT non fanno parte del riferimento variabile; sono delimitatori di espressioni. - In entrambi i casi, l'espressione non deve contenere un riferimento a una variabile; qualsiasi espressione XPath sarebbe stata consentita.
- Non tutti gli attributi in un documento XSLT sono trattati come modelli di valori di attributo. Ad esempio, nota che l'attributo
xsl:value
accetta già un'espressione come contenuto. Domanda : perché non puoi usare
select
in un attributo, come questo?<element attr="<xsl:value-of select="$test"/>"/>
Rispondi : poiché i documenti XSLT devono contenere XML ben formato (e non lo è).
Domanda : perché non puoi utilizzare
{$varname}
nel contenuto dell'elemento?Risposta di Glib : perché i creatori di XSLT non l'hanno progettata in questo modo.
{$config}
funziona solo con gli attributi degli elementi XSLT. (Nota: dollaro all'interno della parentesi graffa perché l'espressione XPath completa deve essere racchiusa tra parentesi graffe)
Usa <xsl:value-of select="$config"/>
invece di {$config}
.
La risposta di @ lwburk è ottima (+1), ma l'ultima domanda / risposta è accurata solo per XSLT 1.0 e 2.0. In 3.0 puoi usare un TVT ( Modello valore testo ; simile all'AVT (Attribute Value Template) menzionato nella risposta di @ lwburk).
Per usare un TVT, aggiungi l'attributo standard xsl:expand-text="yes"
all'elemento. In questo modo il processore tratterà i nodi di testo discendenti di quell'elemento come TVT.
Esempio:
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>
Output (utilizzando qualsiasi XML ben formato come input)
<result>This is Dan's result: BAM!</result>
Nota: testato usando Saxon-PE 9.5.
Perché devi usare <xsl:value-of select="config"/>
?