</xsl:stylesheet>
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='b'>
<c>
<xsl:apply-templates select='@*|node()'/>
</c>
</xsl:template>
<xsl:template match='@*|node()'>
<xsl:copy>
<xsl:apply-templates select='@*|node()'/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Для того чтобы последовательно применить два этих преобразования к некоторому входящему документу a.xml
, мы можем, например, дважды вызвать процессор:
java org.apache.xalan.xslt.Process -IN a.xml -XSL first.xsl -OUT b.xml
java org.apache.xalan.xslt.Process -IN b.xml -XSL second.xsl -OUT c.xml
В результате этих вызовов XSLT-процессор Xalan сначала применит преобразование first.xsl
к документу a.xml
и сохранит результат в файле b.xml
, а затем обработает полученный документ b.xml
при помощи преобразования second.xml
и сохранит результат в файле c.xml
.
В качестве альтернативы, например, для тех случаев, когда пакетная обработка невозможна, мы можем создать преобразование, последовательно применяющее шаблоны преобразований first.xsl
и second.xsl
к входящему документу. Для этого:
□ назначим шаблонам преобразования first.xsl
режим first
, а шаблонам преобразования second.xsl
— режим second
;
□ в основном шаблоне применим шаблоны режима first
к узлам входящего документа, сохранив результат в переменной b
;
□ приведем результирующее дерево, содержащееся в переменной b
ко множеству узлов;
□ обработаем полученное множество узлов шаблонами режима second
.
Следующий листинг демонстрирует предложенный подход.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:xalan='http://xml.apache.org/xalan'
exclude-result-prefixes='xalan'>
<!-- Шаблоны преобразования first -->
<xsl:template match='a' mode='first'>
<b>
<xsl:apply-templates select='@*|node()' mode='first'/>
</b>
</xsl:template>
<xsl:template match='@*|node()' mode='first'>
<xsl:copy>
<xsl:apply-templates select='@*|node()' mode='first'/>
</xsl:copy>
</xsl:template>
<!-- Шаблоны преобразования second -->
<xsl:template match='@*|node()' mode='second'>
<xsl:copy>
<xsl:apply-templates select='@*|node()' mode='second'/>
</xsl:copy>
</xsl:template>
<xsl:template match='b' mode='second'>
<c>
<xsl:apply-templates select='@*|node()' mode='second'/>
</c>
</xsl:template>
<!-- Основное преобразование -->
<xsl:template match='/'>
<!-- Присваиваем переменной а корень входящего документа -->
<xsl:variable name='a' select='/'/>
<!-- Выводим переменную a -->
<xsl:comment> a: </xsl:comment>
<xsl:copy-of select='$a'/>
<!-- Присваиваем переменной b результат обработки переменной a -->
<xsl:variable name='b'>
<xsl:apply-templates select='$a' mode='first'/>
</xsl:variable>
<!-- Выводим переменную b -->
<xsl:comment> b: </xsl:comment>
<xsl:copy-of select='$b'/>
<!-- Присваиваем переменной с результат обработки переменной b -->
<xsl:variable name='c'>
<xsl:apply-templates select='xalan:nodeset($b)' mode='second'/>
</xsl:variable>
<!-- Выводим переменную c -->
<xsl:comment> c: </xsl:comment>
<xsl:copy-of select='$c'/>
</xsl:template>
</xsl:stylesheet>
Ход этого преобразования лучше всего прокомментирует полученный результат.
<а>
<a>1</a>