Re: [xsl] Making nested elements from elements with level attributes

Subject: Re: [xsl] Making nested elements from elements with level attributes
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Thu, 23 Sep 2010 23:57:12 +0100
When you are processing level 4, and the next level is 5, you have a sequence something like this

S4 x x x x S5 x x x S5 x x x S5 x x x

You take everything except the leading S4 - that is, current-group()[position() gt 1], and feed this to the next level of grouping. This does group-starting-with = S5. The first group contains the initial (x x x x) that followed the S4; the subsequent groups each start with an S5. You want to output the initial (x x x x) unchanged, but wrap the other groups in a section element. The logic is

<xsl:for-each-group group-starting-with="S5">
<xsl:choose>
<xsl:when test="current-group()[1] is an element that does not match S5">
<xsl:copy-of select="current-group()"/>
</
<xsl:otherwise>
<section level="5">
         recurse, select="current-group()[position() gt 1]"
</
<
</
</

I hope this gives the idea.

Michael Kay
Saxonica


On 23/09/2010 10:53 PM, russurquhart1@xxxxxxxxxxx wrote:
Thank you! I have modified your suggestions to sort of work. The code is below.

I need to carry to the result tree, the siblings that fall in the current section. I know i need something along the lines of following-sibling: up to next section. Or is there another way to get those in this algorithm.

The current line only get all siblings but the headings.

Any suggestions?

Thank you so much!

Russ

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                 version='2.0' xmlns:xs="http://www.w3.org/2001/XMLSchema";>
<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="section[xs:integer(@level) eq $level]">
     <xsl:element name="Subsection">
       <xsl:value-of select="@level"/>

<!-- I know this line needs to be changed to get the siblings up to the next section element. -->

<xsl:copy-of select="following-sibling::*[name()!='section']"/>

       <xsl:call-template name="process-level">
         <xsl:with-param name="population"
                         select="current-group()[position() != 1]"/>
         <xsl:with-param name="level"
                         select="$level + 1"/>
       </xsl:call-template>
     </xsl:element>
   </xsl:for-each-group>
</xsl:template>
<xsl:template match="article">
   <xsl:call-template name="process-level">
   <xsl:with-param name="population" select="./section"/>
   <xsl:with-param name="level" select="2"/>
   </xsl:call-template>
</xsl:template>
</xsl:stylesheet>


The elegant algorithm IS a recursive routine with a named template: see
http://www.saxonica.com/papers/ideadb-1.1/mhk-paper.xml
for a solution of a similar problem (Stage Two is the relevant part)
Michael Kay
Saxonica

Current Thread