Does any one know how to make the following transformation using xslt?
Source code:
<?xml version="1.0" encoding="UTF-8"?>
<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>
开发者_JAVA百科 </termGrp>
</ntig>
<ntig>
<termGrp>
<term>123</term>
</termGrp>
</ntig>
</langSet>
</termEntry>
</body>
Request:
1.if the value in <term></term> is null\empty, delete its grandparent node, namely
<ntig></ntig>
2.In this way, if all <term> tags are empty, delete the whole <langset> node.
Expected result
<?xml version="1.0" encoding="UTF-8"?>
<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>
The identity transform plus a couple of simple empty templates is what you need here. You want to copy all your input to the output unless it meets your criteria, in which case you want to suppress it.
A stylesheet such as:
<?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="ntig[descendant::term[. = '']]"/>
<xsl:template match="langSet[not(descendant::term[. != ''])]"/>
</xsl:stylesheet>
will do what you need. The template which matches ntig elements will suppress those elements with empty term grandchildren. The template which matches langSet elements suppresses those langSets where there are no descendant term elements which have content.
This transformation:
<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>
when applied on the provided XML document:
<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>
produces the wanted result:
<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>
Explanation:
The identity rule (template) copies every node "as-is".
The template overriding the identity rule for
ntig[not(*/term[string-length()>0])]has an empty body -- this effectively ignores (deletes) anyntigelement that doesn't have at lest onetermgrandchild with positivestring-length().The template overriding the identity rule for
langSet[not(*/*/term[string-length()>0])]has an empty body -- this effectively ignores (deletes) anylangSetelement that doesn't have at lest onetermgreat-grandchild with positivestring-length().
Do note that specifying templates like this violates the definition of the problem:
<xsl:template match="ntig[descendant::term[. = '']]"/>
<xsl:template match="langSet[not(descendant::term[. != ''])]"/>
Because the requirement is to "if the value in is null\empty, delete its grandparent node".
However, the first template above deletes not only the grand-parent ntig, but any ancestor ntig.
The current solution does not commit such a mistake.
加载中,请稍侯......
精彩评论