2012-02-12 13 views
6

Sto imparando xslt e ho una domanda su come posso usare la variabile xslt in diff. per ogni ciclo. So che xslt non è un linguaggio procedurale, quindi non è possibile accedere alla variabile dichiarata in ciclo in un altro ciclo. Ma c'è un modo in cui posso semplicemente dichiarare la variabile globale, quindi assegnare un valore al primo per il ciclo e usare quella variabile nel secondo per il ciclo?scope variabile xslt e il suo utilizzo

Qualsiasi idea sarebbe molto apprezzata.

Grazie

risposta

13

c'è un modo posso solo dichiarare Globa l variabile quindi assegnare un valore in primo per ciclo e utilizzare tale variabile in secondo per ciclo?

Il modo per assegnare un valore ad xsl:variable (ovviamente questa è solo inizializzazione) all'interno di un xsl:for-each, è quello di includere il xsl:for-each nel corpo della variabile.

Ecco un esempio completo:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/*"> 
    <xsl:variable name="vMax"> 
     <xsl:for-each select="num"> 
     <xsl:sort data-type="number" order="descending"/> 

     <xsl:if test="position() = 1"> 
     <xsl:value-of select="."/> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 

    Values close to the maximum: 
<xsl:text/> 

     <xsl:for-each select="num"> 
     <xsl:if test="not($vMax - . > 3) "> 
     <xsl:value-of select="."/> 
     <xsl:text>&#xA;</xsl:text> 
     </xsl:if> 
     </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

Quando questa trasformazione viene applicata sul seguente documento XML ...

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

... it primo definisce una variabile che ottiene vMax il suo valore dal xsl:for-each contenuto nel suo corpo.

Quindi la variabile vMax viene utilizzata nel secondo xsl:for-each per generare tutti i numeri "vicini" al massimo così calcolato.

The Wanted, risultato corretto è prodotta:

 Values close to the maximum: 
07 
08 
09 
10 

E 'anche possibile simulare "l'assegnazione di" una variabile con valori diversi utilizzando una ricorsivo chiamato modello denominato e passare il "nuovo valore" come parametro per il modello chiamato.

Ecco un esempio che mostra questa tecnica. Qui stiamo calcolando il massimo dei valori, contenuti nei nodi di un set di nodi. Ogni volta che accediamo al nodo successivo nel set di nodi, il massimo corrente viene confrontato con questo valore e, se necessario, il nuovo massimo diventa il valore del nodo successivo. Chiamiamo poi lo stesso modello ricorsivamente, passando come il valore della corrente massima del nuovo massima:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/*"> 
    <xsl:call-template name="max"> 
    <xsl:with-param name="pList" select="*"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="max"> 
    <xsl:param name="pMax" select="-99999999"/> 
    <xsl:param name="pList"/> 

    <xsl:choose> 
    <xsl:when test="$pList[1]"> 
     <xsl:variable name="vnewMax" select= 
     "$pMax * ($pMax >= $pList[1]) 
     + 
     $pList[1] * not($pMax >= $pList[1]) 
     "/> 

     <xsl:call-template name="max"> 
     <xsl:with-param name="pMax" select="$vnewMax"/> 
     <xsl:with-param name="pList" select="$pList[position() > 1]"/> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$pMax"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

Quando questa trasformazione viene applicata al documento stesso XML (sopra), il voluto, risultato corretto viene prodotto :

10 
+0

Quindi come potrei ottenere il valore di due campi diversi da utilizzare in seguito? – Julian

+0

Basta definire due variabili e inizializzarle al corrispondente "campo". A proposito di "più tardi" - non esiste una cosa del genere in un linguaggio funzionale. La valutazione può avvenire in qualsiasi ordine e/o in parallelo –

0

xsl:for-each non è un anello in senso esistono for o foreach loop in linguaggi procedurali in modo che qualsiasi domanda parlando di cicli è difficile da capire e più difficile rispondere.

Se si desidera utilizzare le variabili globali in XSLT, è possibile farlo ma si associa un valore alla variabile in cui viene dichiarato (ad esempio globalmente), non è possibile assegnare un valore più avanti in uno for-each come sembra volere fare

0
  1. che hai scritto, 'XSL è una lingua procedurale' .. Beh, non proprio. È una lingua dichiarativa ..
  2. La variabile viene assegnata insieme alla relativa dichiarazione, le variabili non cambiano!
  3. solito seguiamo chiamata ricorsiva per i modelli che utilizzano call-template passando params per loro .. (questo funziona come funzione ricorsiva che chiama con il passaggio di argomenti a linguaggi procedurali)
    Questo è un metodo per gestire i conteggi e condizionale loop ecc ..

saremmo lieti di aiutarvi in ​​caso se si menziona lo scenario esatto con XML di esempio, e l'uscita vi aspettate da esso :)

+0

so che è di 3 anni fa, ma ha scritto * so XSLT non è un linguaggio procedurale * ... – LuckyLikey

+1

@LuckyLikey, controllare la cronologia di modifica della domanda, Dimitri ha corretto esso. In precedenza era "So che XSLT è un linguaggio procedurale" –

+0

hai ragione .. mi dispiace ottenere un +1 – LuckyLikey

Problemi correlati