Applying xslt template one after the other for rem

2020-02-16 04:02发布

问题:

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

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.

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

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

Output

<TargetXML>
    <TagT1>Val</TagT1>
    <TagT2></TagT2>
    <TagT3>
        <TagT4></TagT4>
        <TagT5></TagT5>
    </TagT3>
</TargetXML>

But i want to get an output to be like this

<TargetXML>
    <TagT1>Val</TagT1>
</TargetXML>

Could any one please explain how to achieve the same

回答1:

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>


标签: xml xslt