Решение XSLT 2.0. Я не уверен, что полностью понял точную цель, и поэтому она работает для этого конкретного случая, но, возможно, придется адаптировать ее, если я неправильно понял некоторые требования:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"></xsl:output>
<xsl:template match="/">
<xsl:apply-templates></xsl:apply-templates>
</xsl:template>
<xsl:template match="*|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node[@Group='yes' and not(exists(node()))]"/>
<xsl:template match="node[@Group='yes' and exists(node())]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:copy-of select="node[not(@Group='yes')]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node[@Group='yes' and exists(node())]" mode="groupOnly">
<xsl:copy>
<xsl:apply-templates select="@*[not(name()='Group')]"/>
<xsl:copy-of select="node[@Group='yes']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="navigation">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<node title="Group">
<node>
<xsl:apply-templates select="//node[@Group='yes' and exists(node())]" mode="groupOnly"/>
</node>
</node>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Идея состоит в том, чтобы пройтись по всему дереву, элемент за элементом, это дело шаблона match="*|@*"
, а затем создать отдельный шаблон для каждого элемента, который в этом нуждается.
Затем я использую другой режим для разных случаев: режим по умолчанию для копии узла в ранее существовавшем узле. Режим groupOnly
для узла, который я копирую в новый элемент узла.