Это преобразование :
<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="ntig[not(*/term[string-length()>0])]"/>
<xsl:template match="langSet[not(*/*/term[string-length()>0])]"/>
</xsl:stylesheet>
при применении к предоставленному документу XML :
<body>
<termEntry id="1">
<langSet lang="eng-us">
<ntig>
<termGrp>
<term></term>
</termGrp>
</ntig>
<ntig>
<termGrp>
<term></term>
</termGrp>
</ntig>
</langSet>
<langSet lang="ara-ae">
<ntig>
<termGrp>
<term>123</term>
</termGrp>
</ntig>
</langSet>
</termEntry>
<termEntry id="2">
<langSet lang="eng-us">
<ntig>
<termGrp>
<term></term>
</termGrp>
</ntig>
<ntig>
<termGrp>
<term></term>
</termGrp>
</ntig>
<ntig>
<termGrp>
<term>123</term>
</termGrp>
</ntig>
</langSet>
</termEntry>
</body>
дает желаемый результат :
<body>
<termEntry id="1">
<langSet lang="ara-ae">
<ntig>
<termGrp>
<term>123</term>
</termGrp>
</ntig>
</langSet>
</termEntry>
<termEntry id="2">
<langSet lang="eng-us">
<ntig>
<termGrp>
<term>123</term>
</termGrp>
</ntig>
</langSet>
</termEntry>
</body>
Объяснение
Правило идентификации (шаблон) копирует каждый узел "как есть".
Шаблон, переопределяющий правило идентификации для ntig[not(*/term[string-length()>0])]
, имеет пустое тело - это фактически игнорирует (удаляет) любой элемент ntig
, который не имеет хотя бы одного term
внука с положительным string-length()
.
Шаблон, переопределяющий правило идентификации для langSet[not(*/*/term[string-length()>0])]
, имеет пустое тело - это фактически игнорирует (удаляет) любой элемент langSet
, который не имеет хотя бы одного term
правнука с положительным string-length()
.
Обратите внимание , что указание таких шаблонов нарушает определение проблемы:
<xsl:template match="ntig[descendant::term[. = '']]"/>
<xsl:template match="langSet[not(descendant::term[. != ''])]"/>
Поскольку требование состоит в том, чтобы "если значение в равно null \ empty, удалите его grandparent node".
Однако первый шаблон выше удаляет не только прародителя ntig
, но и любого предка ntig
.
Текущее решение не допускает такой ошибки .