[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] XSLT 2.0 & Grouping - Good Solution - Thanks


Subject: Re: [xsl] XSLT 2.0 & Grouping - Good Solution - Thanks
From: Mark Brand <mark.brand@xxxxxxxxxxxxxxxxxxxx>
Date: Wed, 06 Aug 2003 12:11:22 +1000

Michael Kay wrote:



-----Original Message-----
From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Mark Brand
Sent: 05 August 2003 17:11
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] XSLT 2.0 & Grouping



Hi all


I am having some issues with understanding the for-each-group mechanism in XSLT 2.0
and how I can apply it to my particular situation. Michael Kay yesterday pointed me at some positional grouping information which may appear to offer a solution. But i can't get my head around how to manage the nesting aspects. That is having to output
an opening <PART> tag and then managing all the child tags and then coming back somehow to put in the closing </PART> tag. I am using XSLT 2.0 Saxon 7.5 and I would really like some help on this - as I am a bit stuck.


===Problem Context =============================================
I need to iterate through each paragraph in the Source XML document (below) and depending on what the paragraph style is i need to output some markup & content whilst keeping the nesting (PARTS, contain DIVISIONS, contain SUBDIVISIONS contain REGULATIONS contain SUB-REGULATIONS etc.) intact



I think that what you need here is a nested set of for-each-groups, one for each level of the output tree. In this case it is quite deeply nested:

<xsl:template match="Document"
<xsl:for-each-group select="Paragraph" group-starting-with="*[@StyleName='PART']">
<Part Category="PART">
<xsl:copy-of select="child::node()"/>
<xsl:for-each-group select="current-group() except ."
group-starting-with="*[@StyleName='DIVISION']">
<Part Category="DIVISION">
<xsl:copy-of select="child::node()"/>
<xsl:for-each-group select="current-group() except ."


group-starting-with="*[@StyleName='SUBDIVISION']">

and so on.

It might be possible to make the code neater by making it table-driven:

<xsl:template match="Document"
<xsl:for-each-group select="Paragraph" group-starting-with="*[@StyleName='PART']">
<xsl:apply-templates select="."/>
</xsl:template>


<xsl:template match="Paragraph">
 <Part Category="{@StyleName}">
   <xsl:copy-of select="child::node()"/>
   <xsl:for-each-group select="current-group() except ."
      group-starting-with="*[@StyleName=f:child(@StyleName)]">
     <xsl:apply-templates select="."/>
   </
 </
</

<xsl:function name="f:child" as="xs:string">
<xsl:param name="level" as="xs:string">
<xsl:choose>
<xsl:when test="$level='PART'">DIVISION</xsl:when>
<xsl:when test="$level='DIVISION'">SUBDIVISION</xsl:when>
etc
</


=== Source XML Document ========================================
<Document>
   <Paragraph StyleName="PART">..................</Paragraph>
   <Paragraph StyleName="DIVISION">..............</Paragraph>
   <Paragraph StyleName="SUBDIVISION">...........</Paragraph>
   <Paragraph StyleName="REGULATION">............</Paragraph>
   <Paragraph StyleName="SUB-REGULATION">........</Paragraph>
   <Paragraph StyleName="PARAGRAPH">.............</Paragraph>
   <Paragraph StyleName="SUB-PARAGRAPH">.........</Paragraph>
   <Paragraph StyleName="SUB-PARAGRAPH">.........</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="SUB-PARAGRAPH">.........</Paragraph>
   <Paragraph StyleName="SUB-PARAGRAPH">.........</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="PARAGRAPH">.............</Paragraph>
   <Paragraph StyleName="SUB-PARAGRAPH">.........</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="SUB-PARAGRAPH">.........</Paragraph>
   <Paragraph StyleName="SUB-PARAGRAPH">.........</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="SUB-SUB-PARAGRAPH">.....</Paragraph>
   <Paragraph StyleName="SUB-PARAGRAPH">.........</Paragraph>
   <Paragraph StyleName="SUB-REGULATION">........</Paragraph>
   <Paragraph StyleName="SUB-REGULATION">........</Paragraph>
   <Paragraph StyleName="SUB-REGULATION">........</Paragraph>
   <Paragraph StyleName="SUB-REGULATION">........</Paragraph>
   <Paragraph StyleName="NOTE">..................</Paragraph>
</Document>

=== Required Output ======================
<Regulation>
   <Part Category="PART">
       <Part Category = "DIVISION">
           <Part Category = "SUBDIVISION">
               <Article>
                   <Sub-Article>
                       <Paragraph>
                           <Sub-Paragraph/>
                           <Sub-Paragraph>
                               <Sub-Sub-Paragraph>
                               <Sub-Sub-Paragraph>
                           <Sub-Paragraph/>
                           <Sub-Paragraph/>
                           <Sub-Paragraph>
                               <Sub-Sub-Paragraph/>
                               <Sub-Sub-Paragraph/>
                           </Sub-Paragraph>
                       </Paragraph>
                   </Sub-Article>
              </Article>
           </Part>
       </Part>
   </Part>
</Regulation>


Best Regards & Thanks Mark Brand



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





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



Thanks Michael, much appreciated, I chose not to use your second option, as the first is more than elegant enough for me.




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




Current Thread
Keywords