Re: [xsl] following-sibling on attributes

Subject: Re: [xsl] following-sibling on attributes
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 5 Sep 2003 05:48:24 -0700 (PDT)
Attributes cannot be specified on any of the siblings axis and attributes
are not siblings.

This transformation:

<xsl:stylesheet version="1.0" 
 <xsl:output omit-xml-declaration="yes"/>
  <xsl:template match="TEXT[@*[. = '1']]">
    <xsl:call-template name="att2Element">
      <xsl:with-param name="pAttList" select="@*[. = '1']"/>
  <xsl:template name="att2Element">
    <xsl:param name="pAttList" select="/.."/>
    <xsl:if test="$pAttList">
      <xsl:element name="{name($pAttList[1])}">
          <xsl:when test="$pAttList[2]">
            <xsl:call-template name="att2Element">
              <xsl:with-param name="pAttList"
               select="$pAttList[position() > 1]"/>
            <xsl:value-of select=".."/>

when applied to your source.xml:

<TEXT i="1" b="1"> Lorem ipsum dolor sit amet</TEXT>

produces the wanted result:

<i><b> Lorem ipsum dolor sit amet</b></i>

Note that one cannot expect/rely on the ordering of attributes as it is


Dimitre Novatchev. -- the home of FXSL

---- Vidar S. Ramdal  wrote: --------------------------------------------

I have an XML fragment like this:
<TEXT i="1" b="1"> Lorem ipsum dolor sit amet</TEXT>

The attributes are more or less arbitrary, might also be other 
attributes on this element, like 'u'.
For now, let's suppose that all available attributes have equivalent 
HTML elements (<b> , <i>, <u>).

I want to transform this into something more XHTML-like, so that the 
above fragment should be represented by
<i> <b>Lorem ipsum dolor sit amet</b></i>

I have started off with this XSLT:
     <!-- Matches any TEXT that has one or more attributes --> 
     <xsl:template match="TEXT[attribute::node()]"> 
         <xsl:apply-templates select="attribute::node()[1]"> 
             <xsl:with-param name="content" select="text()"/> 

     <!-- Recursive template that deals with attribute nodes --> 
     <xsl:template match="TEXT/attribute::node()"> 
         <xsl:param name="content"/> 
         <xsl:variable name="newcontent"> 
           <xsl:element name="{local-name(.)}"> 
               <xsl:copy-of select="$content"/> 
           <!-- Problem: This is never true --> 
           <xsl:when test="preceding-sibling::node()"> 
              <xsl:apply-templates select="preceding-sibling::node()[1]"> 
                  <xsl:with-param name="content" select="$newcontent"/> 
             <xsl:copy-of select="$newcontent"/> 

The first template matches the TEXT element ok, and then applies the 
second template to its first attribute. This works fine.

The purpose of the second template is to create an element with the same 
name as the matching attribute. The result is captured in $newcontent.
Then we should look for other attributes on the same parent element, and 
apply templates to those as well.

The problem is that <xsl:when test="preceding-sibling::node()">  
apparently never returns true. The same goes for <xsl:apply-templates 
select="preceding-sibling::node()[1]">  which seems to select nothing.

The result I get with the above XML and stylesheet is
<b> Lorem ipsum dolor sit amet</b>
while I want
<i> <b>Lorem ipsum dolor sit amet</b></i>


Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software

 XSL-List info and archive:

Current Thread