[xsl] Re: Unwrapping trees

Subject: [xsl] Re: Unwrapping trees
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Thu, 13 Jun 2002 11:05:18 -0700 (PDT)
Norman Walsh <ndw at nwalsh dot com> wrote:

> Has anyone written the XSLT required to "unwrap" nested links?
> 
> I'd like to turn, for example:
> 
> <p>
>   text
>   <a href="1">
>     text
>     <span>
>       <a href="2">test</a>
>       text
>     </span>
>     text
>   </a>
>   text
> </p>
> 
> into
> 
> <p>
>   text
>   <a href="1">
>     text
>     <span/>
>   </a>
>   <span>
>     <a href="2">test</a>
>     text
>   </span>
>   <a href="1">
>     text
>   </a>
>   text
> </p>
> 
> With extra bonus points for discarding the empty span (if it doesn't
> have an ID :-)
> 
>                                         Be seeing you,
>                                           norm

Hi Norm,

The following transformation:

unwrapA.xsl:
-----------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

<xsl:strip-space elements="*"/>
  
  <xsl:template match="a[span/a]" name="tA">
    <xsl:if test="node()[not(self::span and a) 
                        and 
                         following-sibling::span[a]
                         ]">
      <xsl:copy>
        <xsl:copy-of select="@* 
                     | node()[not(self::span and a) 
                           and 
                              following-sibling::span[a]
                              ]"/>
      </xsl:copy>
    </xsl:if>
    
    <xsl:apply-templates select="span[a]"/>
    
    <xsl:if test="node()[not(self::span and a) 
                        and 
                         preceding-sibling::span[a]
                         ]">
    
      <xsl:copy>
        <xsl:copy-of select="@* 
                     | node()[not(self::span and a) 
                           and 
                              preceding-sibling::span[a]
                              ]"/>
      </xsl:copy>
    </xsl:if>
    
  </xsl:template>
  
  <xsl:template match="/ | @* | node()">
    <xsl:copy>
      <xsl:apply-templates  select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

when applied on this source xml 

unwrapA.xml:
-----------
<p>
  text
  <a href="1">
    text1
    <span>
      <a href="2">test</a>
      text
    </span>
    text2
  </a>
  text
</p>


Produces this result:


<p>
  text
  <a href="1">
    text1
    </a>
   <span>
      <a href="2">test</a>
      text
    </span>
   <a href="1">
    text2
  </a>
  text
</p>

It seems to me that i get the extra bonus points, too?

Cheers,
Dimitre Novatchev.




__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread