Re: [xsl] Remove element that all its descendants have no text nodes

Subject: Re: [xsl] Remove element that all its descendants have no text nodes
From: Israel Viente <israel.viente@xxxxxxxxx>
Date: Thu, 11 Feb 2010 12:34:41 +0200
Thank you Ken, it works very good.
I didn't understand why we need the second rule too.

<xsl:template match="span[not(*) and not(normalize-space(.))]">
</xsl:template>

If you have time to explain a bit how this combination works I'll be very
happy.

Thanks again, Israel

On Thu, Feb 11, 2010 at 12:46 AM, G. Ken Holman
<gkholman@xxxxxxxxxxxxxxxxxxxx> wrote:
> At 2010-02-11 00:07 +0200, Israel Viente wrote:
>>
>> I want to remove span elements that have empty text nodes and no
>> further descendants.
>> In case the p has ONLY empty spans I want to remove it alltogether.
>>
>> Example:
>>
>> <p dir="rtl"><span id="textStyle10"></span></p>
>> <p dir="rtl"><span id="textStyle10">Some text.</span> <span
>> id="textStyle10"></span></p>
>> <p dir="rtl"><span id="textStyle10"></span><sup>1</sup></p>
>> <p dir="rtl"><span id="textStyle10"><br /><br /></span></p>
>>
>>
>> Desired output:
>> <p dir="rtl"><span id="textStyle10">Some text.</span> </p>
>> <p dir="rtl"><sup>1</sup></p>
>> <p dir="rtl"><span id="textStyle10"><br /><br /></span></p>
>>
>>
>> In case it is too complicated I can live with such output (remove p
>> that all its spans have empty text nodes):
>> <p dir="rtl"><span id="textStyle10">Some text.</span> <span
>> id="textStyle10"></span></p>
>> <p dir="rtl"><span id="textStyle10"></span><sup>1</sup></p>
>> <p dir="rtl"><span id="textStyle10"><br /><br /></span></p>
>>
>> I tried the following:
>> <xsl:template match="p[span[normalize-space(.)='']]"/>
>> but it removes the p even if only one span is empty.
>
> Did you try:
>
>  <xsl:template match="p[span[normalize-space(.)='' and not(*)] and
>                        not(span[normalize-space() or *]) and
>                        not(*[not(self::span)])]"/>
>
> ... which will remove the paragraph if there is at least one empty span, no
> non-empty spans, and nothing other than a span element child.
>
> A working illustration for XSLT 1 is below.  For XSLT 2 you can use:
>
>  <xsl:template match="p[span[normalize-space(.)='' and not(*)] and
>                        not(span[normalize-space() or *]) and
>                        not(* except span)]"/>
>
> I hope this helps.
>
> . . . . . . . . . .  Ken
>
> T:\ftemp>type israel.xml
> <test>
> <p dir="rtl"><span id="textStyle10"></span></p>
> <p dir="rtl"><span id="textStyle10">Some text.</span> <span
> id="textStyle10"></span></p>
> <p dir="rtl"><span id="textStyle10"></span><sup>1</sup></p>
> <p dir="rtl"><span id="textStyle10"><br /><br /></span></p>
> </test>
> T:\ftemp>xslt israel.xml israel.xsl
> <?xml version="1.0" encoding="utf-8"?><test>
>
> <p dir="rtl"><span id="textStyle10">Some text.</span> </p>
> <p dir="rtl"><sup>1</sup></p>
> <p dir="rtl"><span id="textStyle10"><br/><br/></span></p>
> </test>
> T:\ftemp>type israel.xsl
> <?xml version="1.0" encoding="US-ASCII"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>                version="2.0">
>
> <xsl:template match="p[span[normalize-space(.)='' and not(*)] and
>                     not(span[normalize-space() or *]) and
>                     not(*[not(self::span)])]"/>
>
> <xsl:template match="span[not(*) and not(normalize-space(.))]">
> </xsl:template>
>
> <xsl:template match="@*|node()"><!--identity for all other nodes-->
>  <xsl:copy>
>    <xsl:apply-templates select="@*|node()"/>
>  </xsl:copy>
> </xsl:template>
>
> </xsl:stylesheet>
>
> T:\ftemp>
>
>
> --
> XSLT/XQuery/XPath training after http://XMLPrague.cz 2010-03-15/19
> XSLT/XQuery/XPath training:   San Carlos, California 2010-04-26/30
> Vote for your XML training:   http://www.CraneSoftwrights.com/s/i/
> Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
> Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
> Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
> Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
> G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
> Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
> Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread