Sí.
I. Esta transformación XSLT 1.0:
<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>
cuando se aplica en este 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>
hacer la nota:
dos transformaciones se llevan a cabo en realidad, la segunda se realiza en el resultado de la primera.
El resultado de la primera transformación es el contenido de la variable $vrtfPass1
.
En XSLT 1.0 del tipo de variables que contienen dinámicamente generado árboles (temporal) XML (documento XML o fragmento XML) es RTF (resultado-Tree-Fragmento). No es posible realizar operaciones XPath en un RTF; debe convertirse a un conjunto de nodos normal mediante la función de extensión xxx:node-set()
, que es proporcionada por la gran mayoría de los proveedores de procesadores XSLT 1.0. En este ejemplo se usa exslt: node-set(), porque EXSLT es implementado por muchos proveedores diferentes.
La segunda transformación se aplica al resultado del primer: <xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>
. Se usa un mode
por separado para separar limpiamente el código de las dos transformaciones.
La primera transformación multiplica cada num/text()
por 2. La segunda transformación incrementa cada num/text()
. El resultado es 2*.+1
II. Esta transformación 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>
cuando se aplica en el mismo documento XML, produce el mismo resultado deseado y correcta.
Nota: En XSLT 2.0/XPath 2.0, se ha eliminado el tipo de RTF. No es necesaria la función de extensión xxx:node-set()
.
¿Desea que las dos transformaciones se realicen en una sola pasada? Y si es así, ¿por qué no cortar al intermediario y simplemente transformar directamente a su producción prevista? – recursive
¿Por qué necesita que esto suceda con un solo XSLT? ¿Por qué no tener dos archivos separados? –
Tengo una aplicación que solo acepta un archivo XSLT pero quiero aplicar la segunda transformación al archivo recién transformado. – koumides