一个接一个地应用 xslt 模板以删除空节点 [英] Applying xslt template one after the other for removing empty nodes

查看:27
本文介绍了一个接一个地应用 xslt 模板以删除空节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个 xslt 来转换一个 xml.但是生成的 xml 可能有一些空节点,具体取决于源 XML.

I have written one xslt to transform one xml. But the resulting xml may have some empty nodes depending on the source XMl.

现在我想删除那些没有值的空节点.我找到了一些表达式通配符表达式来删除空标签.但我无法将其应用于我现有的 xslt.

Now i want to remove those empty nodes with no values. I have found some expressions wild card expressions to remove the empty tags. But i am not able to apply the same to my existing xslt.

如何在一张表中定义多个 xsl 模板,以便第一个将转换我的源 xml,第二个将取出第一个转换的输出并删除空元素或节点

How can i define multiple xsl templates in one sheet so that first one will transform my source xml and the second one will take the out put of first transformation and remove the empty elements or nodes

源 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>

任何人都可以解释如何实现相同的

Could any one please explain how to achieve the same

推荐答案

如果您愿意,可以将第一次传递的结果存储在一个变量中,然后对结果应用更多模板,仅传递具有实际值的节点:

If you prefer, you can store the results of the first pass in a variable, then apply more templates to the result, passing only nodes with actual values:

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>

这篇关于一个接一个地应用 xslt 模板以删除空节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆