xsl-list
[Top] [All Lists]

Re: Finding sequences of same element

2005-02-09 01:38:06
Hi Simon,
  Please try this XSL -

<?xml version="1.0"?> 
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
 
 <xsl:output method="xml" indent="yes" /> 
  
 <xsl:template match="/A">  
  <A>
   <xsl:for-each select="*">
     <xsl:choose>
       <xsl:when test="not(self::B)">
         <xsl:copy-of select="." />
       </xsl:when>
       <xsl:when test="name(preceding-sibling::*[1])
!= 'B'">
         <D>
           <xsl:copy-of select="." />
           <xsl:call-template name="create-group">
             <xsl:with-param name="list"
select="following-sibling::*" />
           </xsl:call-template>
         </D>
       </xsl:when>
     </xsl:choose>
   </xsl:for-each>
  </A> 
 </xsl:template>
 
 <xsl:template name="create-group">
   <xsl:param name="list" />
      
   <xsl:if test="name($list[1]) = 'B'">
     <xsl:copy-of select="$list[1]" />
     <xsl:call-template name="create-group">
       <xsl:with-param name="list"
select="$list[position() > 1]" />
     </xsl:call-template>
   </xsl:if>   
 </xsl:template>
 
</xsl:stylesheet>

Regards,
Mukul

--- Simon Kissane <skissane(_at_)gmail(_dot_)com> wrote:

Hi

Suppose I have an input document:
<A><B X="1"/><B X="2"/><B X="3"/><C X="4"/><B
X="5"/><B X="6"/><B X="7"/></A>

Now, suppose I wish to group together consecutive B
elements, giving a
result document like this:
<A><D><B X="1"/><B X="2"/><B X="3"/></D><C
X="4"/><D><B X="5"/><B
X="6"/><B X="7"/></D></A>

How can I do this? (I would prefer not to use
recursive templates, but
rather for-each, if that is at all possible...)

I think I can find the initial element of these
sequences, like so:
  B[not(preceding-sibling::*) or
preceding-sibling::*[0][not(self::B)]]
This, I think, should select all B for which there
are either no
preceeding sibling elements, or for which the
immediately preceeding
sibling element is not a B element. Thus, in the
above example, it
would pick B[(_at_)X=1] and B[(_at_)X=5](_dot_)

But, given each initial sequence element, how can I
find the remaining
nodes in the sequence?  With the initial sequence
element as the
context node, I could do:
    .|following-sibling::B
But that will also pick up B[(_at_)X=5] and B[(_at_)X=6] when
the context node is B[(_at_)X=1](_dot_)

Is there a predicate test I could use on
following-sibling::B to
restrict it only to the current sequence of B
elements?

Thanks

Simon Kissane



                
__________________________________ 
Do you Yahoo!? 
The all-new My Yahoo! - What will yours do?
http://my.yahoo.com 

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>