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

RE: [xsl] XSLT 2.0 & Grouping


Subject: RE: [xsl] XSLT 2.0 & Grouping
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Tue, 5 Aug 2003 18:43:52 +0100


> -----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



Current Thread
Keywords