RE: [xsl] following-sibling problem

Subject: RE: [xsl] following-sibling problem
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 27 Oct 2004 14:38:05 +0100
This looks like the classical "positional grouping" problem in its recursive
form.

For a very similar problem I used:

<xsl:template name="process-level">
  <xsl:param name="population" required="yes" as="element()*"/>
  <xsl:param name="level" required="yes" as="xs:integer"/>
  <xsl:for-each-group select="$population" 
                      group-starting-with="*[xs:integer(@level) eq $level]">
    <xsl:element name="{@tag}">
      <xsl:copy-of select="@ID[string(.)], @REF[string(.)]"/>
      <xsl:value-of select="normalize-space(@text)"/>
      <xsl:call-template name="process-level">
        <xsl:with-param name="population" select="current-group() except
."/>
        <xsl:with-param name="level" select="$level + 1"/>
      </xsl:call-template>
    </xsl:element>
  </xsl:for-each-group>
</xsl:template>

Prime this with the population parameter set to the entire sequence of key
elements, and level set to 0, and it will build the hierarchy for you; you
only need to change the instructions that construct new elements and
attributes in the new hierarchy.

Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: Bruce D'Arcus [mailto:bdarcus@xxxxxxxxxxxxx] 
> Sent: 27 October 2004 13:56
> To: XSL-List@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] following-sibling problem
> 
> This is driving me crazy.
> 
> Source:
> 
> 			<bullets>
> 				<bullet level="0" 
> marker-type="inherited">
> 					<content>Heading</content>
> 				</bullet>
> 				<bullet level="1" 
> marker-type="inherited">
> 					<content>Bullet 1a</content>
> 				</bullet>
> 				<bullet level="1" 
> marker-type="inherited">
> 					<content>Bullet 1b</content>
> 				</bullet>
> 				<bullet level="2" 
> marker-type="inherited">
> 					<content>Bullet 2a - "a 
> quote''</content>
> 				</bullet>
> 				<bullet level="2" 
> marker-type="inherited" id="bullet-1">
> 					<content>Bullet 2b</content>
> 				</bullet>
> 			</bullets>
> 
> Templates:
> 
> <xsl:template match="key:bullet[@level='0']" mode="normal">
>    <h2><xsl:value-of select="."/></h2>
>    <ul>
>      <xsl:apply-templates 
> select="following-sibling::key:bullet[@level='1']"/>
>    </ul>
> </xsl:template>
> 
> <xsl:template match="key:bullet[@level='1']">
>    <li class="level1">
>      <xsl:value-of select="."/>
>      <xsl:if test="following-sibling::key:bullet[@level='2']">
>        <ul>
>          <xsl:apply-templates 
> select="following-sibling::key:bullet[@level='2']"/>
>        </ul>
>      </xsl:if>
>    </li>
> </xsl:template>
> 
> <xsl:template match="key:bullet[@level='2']">
>    <li class="level2">
>      <xsl:value-of select="."/>
>    </li>
> </xsl:template>
> 
> 
> Output:
> 
>          <h2>Heading</h2>
>          <ul>
>            <li class="level1">Bullet 1a<ul>
>                <li class="level2">Bullet 2a - "a quote''</li>
>                <li class="level2">Bullet 2b</li>
>              </ul>
>            </li>
>            <li class="level1">Bullet 1b<ul>
>                <li class="level2">Bullet 2a - "a quote''</li>
>                <li class="level2">Bullet 2b</li>
>              </ul>
>            </li>
>          </ul>
> 
> What I want:
> 
>          <h2>Heading</h2>
>          <ul>
>            <li class="level1">Bullet 1a</li>
>            <li class="level1">Bullet 1b<ul>
>                <li class="level2">Bullet 2a - "a quote''</li>
>                <li class="level2">Bullet 2b</li>
>              </ul>
>            </li>
>          </ul>
> 
> In other words, I only want the template for level 2 applied 
> when there 
> is a following-sibling immediately following a level 1 bullet.
> 
> Bruce

Current Thread