Более простое, короткое и универсальное решение (без указания имен элементов) :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*[not(*[2])]">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/*/*/node()"/>
</xsl:stylesheet>
, когда это преобразование применяется к первому предоставленному XML-документу (исправлено, чтобы быть правильно сформированным):
<root>
<branch>
<foo>bar</foo>
</branch>
</root>
желаемый, правильный результат получается :
<branch></branch>
Когда то же самое преобразованиеприменяется ко второму предоставленному XML-документу (снова необходимо исправить для корректности):
<root>
<branch>
<foo>bar</foo>
</branch>
<branch>
<foo>baz</foo>
</branch>
</root>
снова желаемый, правильный выходной результат :
<root>
<branch></branch>
<branch></branch>
</root>
Объяснение :
Правило идентификации копирует каждый узел "как есть".
Существует два шаблона, которые переопределяют шаблон идентификации для определенных узлов и обрабатывают эти узлы по-разному.
Первый переопределяющий шаблон соответствует верхнемуэлемент, который не имеет второго дочернего элемента.Он не копирует сам элемент, а обрабатывает его дочерние элементы.
Второй переопределяющий шаблон соответствует любому элементу, являющемуся потомком верхнего элемента.Этот шаблон не имеет тела, что означает, что все такие совпадающие элементы игнорируются и не включаются в вывод (другими словами - «удалены»)
Doпримечание :
Это преобразование может быть применено к любому XML-документу независимо от имен элементов в нем и по-прежнему дает требуемый, правильный результат.
Например, , при применении к этому документу XML:
<t>
<b>
<f>brrr</f>
</b>
<b>
<f>bzzz</f>
</b>
</t>
желаемый, правильный результат получается :
<t>
<b></b>
<b></b>
</t>
Сравните это с результатом, полученным в настоящее время принятым ответом :
<t>
<b>
<f>brrr</f>
</b>
<b>
<f>bzzz</f>
</b>
</t>