我写了一个xslt来转换一个xml。但是生成的xml可能有一些空节点,具体取决于源XMl。
现在我想删除那些没有值的空节点。我找到了一些表达式外卡表达式来删除空标签。但我无法将其应用于现有的xslt。
如何在一个工作表中定义多个xsl模板,以便第一个将转换我的源xml,第二个将获取第一个转换的输出并删除空元素或节点
源XML
<?xml-stylesheet type="text/xsl" href="TTT.xsl"?>
<SourceXML>
<Tag1>Val</Tag1>
<Tag2></Tag2>
<Tag3>
<Tag4></Tag4>
<Tag5></Tag5>
</Tag3>
</SourceXML>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/">
<TargetXML>
<TagT1>
<xsl:value-of select=".//Tag1" />
</TagT1>
<TagT2>
<xsl:value-of select=".//Tag2" />
</TagT2>
<TagT3>
<TagT4>
<xsl:value-of select=".//Tag3/Tag4" />
</TagT4>
<TagT5>
<xsl:value-of select=".//Tag3/Tag5" />
</TagT5>
</TagT3>
</TargetXML>
</xsl:template>
</xsl:stylesheet>
输出
<TargetXML>
<TagT1>Val</TagT1>
<TagT2></TagT2>
<TagT3>
<TagT4></TagT4>
<TagT5></TagT5>
</TagT3>
</TargetXML>
但我希望得到一个像这样的输出
<TargetXML>
<TagT1>Val</TagT1>
</TargetXML>
任何人都可以解释如何实现相同的
答案 0 :(得分:2)
如果您愿意,可以将第一遍的结果存储在变量中,然后将更多模板应用于结果,仅传递具有实际值的节点:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- first pass -->
<xsl:template match="/" mode="first-pass">
<TargetXML>
<TagT1>
<xsl:value-of select=".//Tag1" />
</TagT1>
<TagT2>
<xsl:value-of select=".//Tag2" />
</TagT2>
<TagT3>
<TagT4>
<xsl:value-of select=".//Tag3/Tag4" />
</TagT4>
<TagT5>
<xsl:value-of select=".//Tag3/Tag5" />
</TagT5>
</TagT3>
</TargetXML>
</xsl:template>
<xsl:template match="/">
<!-- apply first pass -->
<xsl:variable name="first-pass">
<xsl:apply-templates select="." mode="first-pass"/>
</xsl:variable>
<!-- final output -->
<xsl:apply-templates select="exsl:node-set($first-pass)/*"/>
</xsl:template>
<xsl:template match="*[normalize-space(descendant::text()) or descendant-or-self::*/@*[string()]]">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*[string()]">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>