Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Xslt - Ignore empty elements 1

Status
Not open for further replies.

dv1

Technical User
May 15, 2009
8
US
I need my xslt document to ignore empty elements. This is what I currently have(thanks tsuji)

Code:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
    <xsl:output method="xml" encoding="utf-8" indent="yes" />

    <xsl:template match="/">
        
        <Root>
            <xsl:apply-templates select="*/*[starts-with(local-name(),'Page')]" mode="acf-proc" />
            
        </Root>
    </xsl:template>

    <xsl:template match="*[starts-with(local-name(),'Page')]" mode="acf-proc">
        
        
        <xsl:copy>
            <xsl:apply-templates select="*/*[local-name()='p']" mode="acf-proc" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[local-name()='p']" mode="acf-proc">
        <xsl:apply-templates select="text()|*[local-name()='span']" mode="acf-proc" />
    </xsl:template>
    <xsl:template match="text()" mode="acf-proc">
        <xsl:variable name="b" select="contains(parent::*/@style,'font-weight:bold')" />
        <xsl:variable name="t" select="contains(parent::*/@style,'font-style:italic')" />
        <xsl:variable name="u" select="contains(parent::*/@style,'text-decoration:underline')" />
        <xsl:choose>
            
            <!-- Bold, Italic and Underlined-->
            <xsl:when test="$b and $t and $u">
                <bolditalic-underline>
                    <xsl:call-template name="spacing" />
                </bolditalic-underline>
            </xsl:when>
            
            <!-- Bold and underlined-->
            <xsl:when test="$b and (not($t)) and $u">
                <bold-underline>
                    <xsl:call-template name="spacing" />
                </bold-underline>
            </xsl:when>
            
            <!-- Italic and underlined-->
            <xsl:when test="(not($b)) and $t and $u">
                <italic-underline>
                    <xsl:call-template name="spacing" />
                </italic-underline>
            </xsl:when>
            
            <!-- Italic-->
            <xsl:when test="(not($b)) and (not($t)) and $u">
                <underline>
                    <xsl:call-template name="spacing" />
                </underline>
            </xsl:when>
            
            <xsl:when test="$b and $t">
                <!--        <bold>
                    <italic> -->
                <bolditalic>
                    <xsl:call-template name="spacing" />
                </bolditalic>
                <!--          </italic>
                    </bold> -->
                
            </xsl:when>
            <xsl:when test="$b and (not($t)) and (not($u))">
                <bold>
                    <xsl:call-template name="spacing" />
                </bold>
            </xsl:when>
            
            <xsl:when test="(not($b)) and $t and (not($u))">
                <italic>
                    <xsl:call-template name="spacing" />
                </italic>
            </xsl:when>
            
            <xsl:otherwise>
                <xsl:call-template name="spacing" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    
    <xsl:template match="*[local-name()='span']" mode="acf-proc">
        <xsl:apply-templates select="text()|*[local-name()='span']" mode="acf-proc" />
    </xsl:template>
    
    <xsl:template name="spacing">
        <xsl:choose>
            <xsl:when test="string-length(normalize-space())=0">
                <xsl:text> </xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="normalize-space()" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

It produces an output looking like this:

Code:
<?xml version="1.0" encoding="utf-8"?>
<Root>
   <Page01_a>Here is some text and here is some more!</Page01_a>
   <Page02_a/>
   <Page02_b>Here is <underline>some text and he</underline>re is some more!</Page02_b>
   <Page02_c/>
   <Page02_d>Here is some<bold>text and here is some more</bold>!</Page02_d>
   <Page02_e/>
   <Page02_f>Here is som<bolditalic-underline>e text and here is some mo</bolditalic-underline>re!</Page02_f>
   <Page02_g/>
   <Page02_h/>
   <Page02_i/>
   <Page02_j/>
 ...
</Root>

But I need it to ignore the empty elements, resulting in this:

Code:
<?xml version="1.0" encoding="utf-8"?>
<Root>
   <Page01_a>Here is some text and here is some more!</Page01_a>
   <Page02_b>Here is <underline>some text and he</underline>re is some more!</Page02_b>
   <Page02_d>Here is some<bold>text and here is some more</bold>!</Page02_d>
   <Page02_f>Here is som<bolditalic-underline>e text and here is some mo</bolditalic-underline>re!</Page02_f>
</Root>
 
Try this.
[tt]
<xsl:template match="*[starts-with(local-name(),'Page')]" mode="acf-proc">
[blue]<xsl:if test="*/*[local-name()='p' and string-length(normalize-space())!=0]">[/blue]
<xsl:copy>
<xsl:apply-templates select="*/*[local-name()='p']" mode="acf-proc" />
</xsl:copy>
[blue]</xsl:if>[/blue]
</xsl:template>
[/tt]
 
Thank you, that works great!

Btw, are there any books on xslt that you would recommend?
 
[1] If the above works, that would mean there is only one node that matches or more than one node that have non empty text() at the same time. To free from that contingency, you can tighten up like this, which is the natural step to take.
[tt]
<xsl:template match="*[starts-with(local-name(),'Page')]" mode="acf-proc">
<xsl:if test="*/*[local-name()='p' and string-length(normalize-space())!=0]">
<xsl:copy>
<xsl:apply-templates select="*/*[local-name()='p' and string-length(normalize-space())!=0]" mode="acf-proc" />
</xsl:copy>
</xsl:if>
</xsl:template>
[/tt]
[2] >are there any books on xslt that you would recommend?
I would recommend an old book of xslt1.0.
Otegem, Michiel van., Sams teach yourself XSLT in 21 days, Sams, 2002.
That would form the basis better than any other books. Tbat mastering of the basic is absolutely necessary for xslt because it involves a different kind of reasoning pattern than the procedural programming, discipline commonly learned.
 
Thank you for all your help. Yes, I have noticed that the reasoning pattern is different, i think that is what's tripping me up, hopefully that book will help.
I purchased the book from amazon, it was only $10!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top