Если вы напишите шаблон для тех потомков MaXML
, у которых есть дочерний элемент с соответствием ключа, вы можете просто дважды использовать шаблон идентификатора для этих элементов-потомков, у меня было явное исключение элементов Rule
, тогда:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="ref" match="MaXML/Rule/*" use="concat(generate-id(ancestor::MaXML), '|', name())"/>
<xsl:template match="MaXML//*[not(self::Rule)][*[key('ref', concat(generate-id(ancestor::MaXML), '|', name()))]]">
<xsl:call-template name="identity"/>
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="Body//*[key('ref', concat(generate-id(ancestor::MaXML), '|', name()))]">
<xsl:copy>
<xsl:value-of select="key('ref', concat(generate-id(ancestor::MaXML), '|', name()))"/>
</xsl:copy>
<!-- duplicate matched node -->
<xsl:element name="{name()}">
<xsl:value-of select="key('ref', concat(generate-id(ancestor::MaXML), '|', name()))"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty -development.net / pPqsHTK / 6
С XSLT 3 это немного проще:
<xsl:template match="MaXML//*[not(self::Rule)][*[key('ref', node-name(), ancestor::MaXML)]]">
<xsl:next-match/>
<xsl:next-match/>
</xsl:template>
https://xsltfiddle.liberty -development.net / pPqsHTK / 8