xsl-list
[Top] [All Lists]

RE: XSLT 2.0 & Grouping

2003-08-05 10:43:52


-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com 
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com] On Behalf Of 
Mark Brand
Sent: 05 August 2003 17:11
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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="*[(_at_)StyleName='PART']">
 <Part Category="PART">
   <xsl:copy-of select="child::node()"/>
   <xsl:for-each-group select="current-group() except ."
                       group-starting-with="*[(_at_)StyleName='DIVISION']">
     <Part Category="DIVISION">
       <xsl:copy-of select="child::node()"/>
       <xsl:for-each-group select="current-group() except ."
 
group-starting-with="*[(_at_)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="*[(_at_)StyleName='PART']">
  <xsl:apply-templates select="."/>
</xsl:template>

<xsl:template match="Paragraph">
  <Part Category="{(_at_)StyleName}">
    <xsl:copy-of select="child::node()"/>
    <xsl:for-each-group select="current-group() except ."
       group-starting-with="*[(_at_)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