Да.
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 (Результат-дерево-фрагмент). В RTF нет операций XPath - его необходимо преобразовать в обычный набор узлов, используя функцию расширения 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()
.
Вы хотите, чтобы две трансформации произошли за один проход? И если да, почему бы не вырезать среднего человека и просто трансформироваться непосредственно в ваш предполагаемый выход? – recursive
Зачем вам это нужно с одним XSLT? Почему бы не создать два отдельных файла? –
У меня есть приложение, которое принимает только один файл XSLT, но я хочу применить второе преобразование к вновь преобразованному файлу. – koumides