Во-первых, обратите внимание, что представленный требуемый вывод неправильный , и у следующего элемента нет конечного тега позже в документе:
<node name = "C">
Результатом оценки выражений XPath может быть набор узлов из документа XML, но эти примечания не могут быть изменены XPath .
Это выражение XPath выбирает
узлов, которые соответствуют термину вместе с
их родители полностью прослеживают
корневой узел
//*[contains(@name,'angles') and not(node())]/ancestor::*
Однако узлы не изменены, и они содержат все свои дочерние элементы, что означает, что полное поддерево с корнем в Root
все еще является поддеревом Root
в возвращенном результате.
Если вы хотите получить новый документ (набор узлов) с структурой, отличной от исходного XML-документа, вы должны использовать другой язык, на котором размещается XPath . Существует много таких языков, таких как XSLT, XQuery и любой язык с реализацией XML DOM.
Вот XSLT-преобразование, дающее желаемый результат :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(descendant-or-self::*[contains(@name, 'angles')])]"/>
</xsl:stylesheet>
когда это преобразование применяется к предоставленному XML-документу (исправлено, чтобы оно было правильно сформировано) :
<root>
<node name = "Amaths">
<node name = "Bangles"/>
</node>
<node name = "C">
<node name = "Dangles">
<node name = "E">
<node name = "Fangles"/>
</node>
<node name = "Gdecimals" />
</node>
</node>
<node name = "Hnumbers"/>
<node name = "Iangles"/>
</root>
желаемый (правильный) результат получается :
<root>
<node name="Amaths">
<node name="Bangles"/>
</node>
<node name="C">
<node name="Dangles">
<node name="E">
<node name="Fangles"/>
</node>
</node>
</node>
<node name="Iangles"/>
</root>