Sì.
I. Questo XSLT 1.0 trasformazione:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vrtfPass1">
<xsl:apply-templates/>
</xsl:variable>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num/text()">
<xsl:value-of select="2*."/>
</xsl:template>
<xsl:template match="num/text()" mode="pass2">
<xsl:value-of select="1+."/>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>
</xsl:template>
</xsl:stylesheet>
quando applicato su questo documento XML:
<t>
<num>1</num>
<num>2</num>
<num>3</num>
<num>4</num>
<num>5</num>
</t>
produce:
<t>
<num>3</num>
<num>5</num>
<num>7</num>
<num>9</num>
<num>11</num>
</t>
Do atto:
due trasformazioni sono in realtà eseguite, la seconda viene eseguita sul risultato della prima.
Il risultato della prima trasformazione è il contenuto della variabile $vrtfPass1
.
in XSLT 1.0 il tipo di variabili che contengono dinamicamente generato alberi (temporanea) XML (documento XML o frammento XML) è RTF (Risultato-Tree-frammento). Non è possibile eseguire operazioni XPath su un RTF: è necessario convertirlo in un normale set di nodi utilizzando la funzione di estensione xxx:node-set()
, fornita dalla maggior parte dei fornitori di processori XSLT 1.0. In questo esempio exslt: viene utilizzato node-set(), poiché EXSLT è implementato da molti fornitori diversi.
La seconda trasformazione viene applicata sul risultato del primo: <xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>
. Viene utilizzato un codice mode
separato per separare in modo pulito il codice delle due trasformazioni.
La prima trasformazione moltiplica ogni num/text()
per 2. La seconda trasformazione incrementa ogni num/text()
. Il risultato è 2*.+1
II. Questa trasformazione XSLT 2.0:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vPass1">
<xsl:apply-templates mode="pass1"/>
</xsl:variable>
<xsl:template match="node()|@*" mode="pass1">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num/text()" mode="pass1">
<xsl:value-of select="2*xs:integer(.)"/>
</xsl:template>
<xsl:template match="num/text()" mode="pass2">
<xsl:value-of select="1+."/>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$vPass1" mode="pass2"/>
</xsl:template>
</xsl:stylesheet>
se applicato sullo stesso documento XML, produce lo stesso risultato voluto e corretta.
Nota: in XSLT 2.0/XPath 2.0 il tipo di RTF è stato abolito. Non è necessaria la funzione di estensione xxx:node-set()
.
fonte
2010-09-09 16:57:48
Vuoi che le due trasformazioni avvengano in un solo passaggio? E se è così, perché non tagliare l'uomo medio e semplicemente trasformarlo direttamente nella produzione desiderata? – recursive
Perché è necessario che ciò accada con un singolo XSLT? Perché non hai due file separati? –
Ho un'app che accetta solo un file XSLT ma voglio applicare la seconda trasformazione al file appena trasformato. – koumides