Да.
I.Это преобразование 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>
при применении к этому документу XML :
<t>
<num>1</num>
<num>2</num>
<num>3</num>
<num>4</num>
<num>5</num>
</t>
создает :
<t>
<num>3</num>
<num>5</num>
<num>7</num>
<num>9</num>
<num>11</num>
</t>
Примечание :
Два преобразования фактически выполняются , второе выполняется по результату первого.
Результатом первого преобразования является содержимое переменной $vrtfPass1
.
В XSLT 1.0 тип переменныхкоторые содержат динамически генерируемые (временные) деревья XML (документ XML или фрагмент XML) - это RTF (Result-Tree-Fragment).Операции XPath невозможны с RTF - его необходимо преобразовать в обычный набор узлов с помощью функции расширения xxx:node-set()
, которая предоставляется подавляющим большинством поставщиков процессоров XSLT 1.0.В этом примере используется exslt: node-set (), поскольку EXSLT реализуется многими различными поставщиками.
Второе преобразование применяется к результату первого : <xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>
.Отдельный mode
используется для четкого разделения кода двух преобразований.
Первое преобразование умножает каждое num/text()
на 2. Второе преобразование увеличивает каждоеnum/text()
.Результат: 2*.+1
II.Это преобразование 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>
при применении к тому же XML-документу дает тот же требуемый и правильный результат .
Примечание: В XSLT 2.0 / XPath 2.0 тип RTF отменен.Нет необходимости в расширении xxx:node-set()
.