Это преобразование использует и переопределяет правило идентификации. Комментарии, следующие сразу за executor
, извлекаются с использованием функции key()
. executor
, invoker
и comment
, следующие сразу за executor
, копируются в специальном режиме с именем people
. В обычном анонимном режиме они сопоставляются с пустым шаблоном, чтобы избежать их повторного копирования:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kExecComments" match=
"comment
[preceding-sibling::*
[not(self::comment)][1]
[self::executor]
]"
use="generate-id(preceding-sibling::executor[1])"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="executor">
<people>
<importantPeople>
<xsl:apply-templates mode="people"
select=".|key('kExecComments', generate-id())"/>
</importantPeople>
<xsl:apply-templates mode="people" select=
"following-sibling::invoker"/>
</people>
</xsl:template>
<xsl:template match="executor|comment|invoker"
mode="people">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match=
"invoker |
comment
[preceding-sibling::*
[not(self::comment)][1]
[self::executor]
]"/>
</xsl:stylesheet>
при применении к предоставленному документу XML :
<testExecution>
<test>
<test.1/>
<test.2/>
<test.3/>
</test>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
<executor>
<executor.1/>
<executor.2/>
<executor.3/>
</executor>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
<invoker>
<invoker.1/>
<invoker.2/>
<invoker.3/>
</invoker>
<recipient>
<recipient.1/>
<recipient.2/>
<recipient.3/>
</recipient>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
</testExecution>
дает желаемый, правильный результат :
<testExecution>
<test>
<test.1/>
<test.2/>
<test.3/>
</test>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
<people>
<importantPeople>
<executor>
<executor.1/>
<executor.2/>
<executor.3/>
</executor>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
</importantPeople>
<invoker>
<invoker.1/>
<invoker.2/>
<invoker.3/>
</invoker>
</people>
<recipient>
<recipient.1/>
<recipient.2/>
<recipient.3/>
</recipient>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
<comment>
<comment.1/>
<comment.2/>
<comment.3/>
</comment>
</testExecution>