有没有人知道如何使用xslt进行以下转换?
源代码:
<?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>
</termGrp>
</ntig>
<ntig>
<termGrp>
<term>123</term>
</termGrp>
</ntig>
</langSet>
</termEntry>
</body>
请求:
1.如果<term></term>
中的值为null \ empty,则删除其祖父节点,即
<ntig></ntig>
2.这样,如果所有<term>
标记都为空,请删除整个<langset>
节点。
预期结果
<?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>
答案 0 :(得分:3)
您需要身份转换以及几个简单的空模板。您希望将所有输入复制到输出中,除非它符合您的条件,在这种情况下您要禁止它。
样式表,例如:
<?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>
将做你需要的。匹配ntig
元素的模板将禁止那些具有空term
个孙子元素的元素。匹配langSet
元素的模板会抑制那些没有带有内容的后代langSets
元素的term
。
答案 1 :(得分:1)
此转化:
<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
个元素的元素有正面的曾孙[{1}}。
请注意指定此类模板违反了问题的定义:
string-length()
因为要求是“如果值in null为空,则删除其祖父母节点”。
但是,上面的第一个模板不仅会删除祖父<xsl:template match="ntig[descendant::term[. = '']]"/>
<xsl:template match="langSet[not(descendant::term[. != ''])]"/>
,还会删除任何祖先 ntig
。
当前解决方案不会犯这样的错误。