Благодаря michael.hor257k и большому беспокойству я наконец-то нашел решение своей проблемы.
Вот мой рабочий код XSLT 1.0
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="@*|node()" priority="0">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()" priority="0" mode="EXTRACT_XREF">
<xsl:param name="i" select="0"/>
<xsl:if test="descendant-or-self::text()[count(preceding-sibling::Xref)=$i]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()" mode="EXTRACT_XREF">
<xsl:with-param name="i" select="$i"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="para[descendant::Xref]" priority="1">
<xsl:call-template name="recursive">
<xsl:with-param name="node" select="."/>
<xsl:with-param name="count" select="0"/>
<xsl:with-param name="limit" select="count(descendant::Xref)"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="recursive">
<xsl:param name="node"/>
<xsl:param name="count" select="0"/>
<xsl:param name="limit"/>
<xsl:if test="$count<=$limit">
<xsl:apply-templates select="$node" mode="EXTRACT_XREF">
<xsl:with-param name="i" select="$count"/>
</xsl:apply-templates>
<xsl:apply-templates select="$node/descendant::Xref[$count + 1]"/>
<xsl:call-template name="recursive">
<xsl:with-param name="node" select="$node"/>
<xsl:with-param name="count" select="$count + 1"/>
<xsl:with-param name="limit" select="$limit"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="Xref" priority="1">
<toolRef>
<xsl:attribute name="ref">
<xsl:value-of select="@ref"/>
</xsl:attribute>
</toolRef>
</xsl:template>
</xsl:transform>
Я также добавил несколько узлов тестирования, которые должны быть скопированы без изменений, чтобы проверить все возможные случаи:
Входной XML
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<dontChangeThisNode></dontChangeThisNode>
<para>
<emphasis mode="bold">
<emphasis mode="underline">blah 0<Xref ref="1"/>blah 1<Xref ref="3"/> blah</emphasis>
</emphasis>
</para>
<dontChangeThisNodeEither>hop</dontChangeThisNodeEither>
<para>blah 2 <Xref ref="2"/> blah 3</para>
<para>blah 4</para>
</parent>
И, наконец, вот чтоэтот код преобразует его в:
вывод XML
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<dontChangeThisNode/>
<para>
<emphasis mode="bold">
<emphasis mode="underline">blah 0</emphasis>
</emphasis>
</para>
<toolRef ref="1"/>
<para>
<emphasis mode="bold">
<emphasis mode="underline">blah 1</emphasis>
</emphasis>
</para>
<toolRef ref="3"/>
<para>
<emphasis mode="bold">
<emphasis mode="underline"> blah</emphasis>
</emphasis>
</para>
<dontChangeThisNodeEither>hop</dontChangeThisNodeEither>
<para>blah 2 </para>
<toolRef ref="2"/>
<para> blah 3</para>
<para>blah 4</para>
</parent>