Удаление дочернего элемента
Добавьте шаблон к преобразованию идентичности , который соответствует дочерним элементам, у которых родительский и дочерний элементы имеют одинаковое QName , а дочерний элемент пропущен:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[name() = name(..)]">
<xsl:apply-templates select="node()"/>
</xsl:template>
</xsl:stylesheet>
Демонстрация на удобной XSLT-скрипте Мартина Хоннена.
Обратите внимание, что вышеприведенный лексически сравнивает QNames, которые могут включать префиксы пространства имен.Чтобы правильно сравнить имена ( семантически ), проверьте URI пространства имен:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[ local-name() = local-name(..)
and namespace-uri() = namespace-uri(..)]">
<xsl:apply-templates select="node()"/>
</xsl:template>
</xsl:stylesheet>
Обновлено demo .
Удаление родительского элемента
В обновленном запросе OP, вот как удалить родительский элемент, когда есть дочерний элемент с таким же именем.Выбирая подход, который следует использовать, учтите, что в общем случае у ребенка может быть только один родитель, но у родителя может быть несколько детей.
Простое QName check :
<xsl:template match="*[*[name() = name(..)]]">
<xsl:apply-templates select="node()"/>
</xsl:template>
URI полного пространства имен check :
<xsl:template match="*[*[ local-name() = local-name(..)
and namespace-uri() = namespace-uri(..)]]">
<xsl:apply-templates select="node()"/>
</xsl:template>
Credit: Благодаря @ Alejandro и @ michael.hor257k за полезные исправления и улучшения.