[xsl] grouping within a group in XSLT1.0

Subject: [xsl] grouping within a group in XSLT1.0
From: Debbie <debbieannepower@xxxxxxxxx>
Date: Thu, 31 Aug 2006 17:09:41 -0230
Hi All,

I need to do a group within a group in XSLT 1.0.  I'm using XALAN to
transform an xml into pdf via FOP 0.20.5.  Here is my problem.

I have an xml document that has a list of questions and their
responses.  These questions are divided up into sections such as
section 1-0-0 and 2-0-0 etc.

What I have to do is bring back a list of unique responses (no
repeats) for the questions in each section and a count for each
response.  The responses can be anything.  So what I need returned is
this:

Section Count

1-0-0
No		3
Yes		2
N/A		1

2-0-0
Not Documented	4
Approved	2
Yes		3

I have tried the meunchian grouping method but couldn't seem to get it
to work. The method I have now fails if there are 3 same responses in
a row.  It puts the first response in the section with the previous
section.  I pretty sure that it's happening because I'm using
preceding and following to check the responses but I can't think of
another way of doing this.  Any suggestions?


My Stylesheet is attached: This is the section of the attached stylesheet that returns the unique responses.

<!--brings back unique responses -->

                  <fo:table-cell>
                   <fo:block font="Arial" text-align="center"
font-size="8pt" font-weight="normal" space-after="2px">
                    <xsl:choose>
                     <xsl:when test="sec_id">
                      <xsl:if test="not(audit_response/resp='')">
                       <xsl:if test="sec_id=$test">										
                        <xsl:for-each
select="audit_response/resp[1][not(.=preceding::audit_response/resp[1])]
| audit_response/resp[1][not(.=following::audit_response/resp[1])]">
                         <xsl:value-of select="."/>
                        </xsl:for-each>
                       </xsl:if>
                      </xsl:if>
                     </xsl:when>
                    </xsl:choose>										
                   </fo:block>							
                  </fo:table-cell>








My Stylesheet:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:date="http://exslt.org/dates-and-times";
xmlns:fo="http://www.w3.org/1999/XSL/Format";
xmlns:xalan="http://xml.apache.org/xalan";
xmlns:java="http://xml.apache.org/xslt/java";
xmlns:exsl="http://exslt.org/common"; xmlns:set="http://exslt.org/sets";
xmlns:dyn="http://exslt.org/dynamic"; extension-element-prefixes="exsl"
exclude-result-prefixes="set">
	<xsl:output/>

	<xsl:key name="response"
match="report/audit/questions/question/audit_response" use="resp"/>
	<xsl:key name="responseNum" match="report/audit/questions/question"
use="resp_num"/>
	<xsl:key name="car" match="report/audit/questions/question"
use="audit_response/corr_acts/corr_act"/>
	<xsl:key name="response2" match="report/audit/questions/question"
use="audit_response/resp"/>
	<xsl:key name="corracts" match="report/audit/questions/question"
use="audit_response/corr_acts/corr_act/id"/>
	<xsl:key name="keys_sec_id" match="report/audit/questions/question"
use="sec_id"/>
	<xsl:key name="resps" match="//resp" use="resp"/>
	<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format";>

<fo:layout-master-set>
<fo:simple-page-master master-name="rptPages" page-height="10in"
page-width="8in" margin-top="1cm" margin-bottom=".5cm"
margin-left="1cm" margin-right="1cm">
 <fo:region-body margin-bottom="1.5cm" margin-top="2cm"
keep-together.within-page="always">
 </fo:region-body>
  <fo:region-after region-name="rptFooter" extent="1cm"/>
   <fo:region-before region-name="rptHeader" extent="2cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="rptPages" force-page-count="no-force">

<!--        REPORT HEADER -->
<fo:static-content flow-name="rptHeader">
<fo:table table-layout="fixed" inline-progression-dimension="18cm"
cell-spacing="0" cell-padding="0">
 <fo:table-column column-width="6cm"/>
  <fo:table-column column-width="9cm"/>
   <fo:table-column column-width="3.5cm"/>
    <fo:table-body>
     <fo:table-row>
      <fo:table-cell>

       <fo:external-graphic width="2.5in" height="0.75in"
src="file:xsl/IATAlogo.jpg" />
      </fo:table-cell>
     </fo:table-row>
      <fo:table-row>
      <fo:table-cell />
     </fo:table-row>
     <fo:table-row>
      <fo:table-cell>
       <fo:block font-size="17pt" font="Arial" font-weight="bold">
<!-- <xsl:value-of select="report/audit/company_name" />-->
       </fo:block>
      </fo:table-cell>
     </fo:table-row>
     <fo:table-row>
      <fo:table-cell>
       <fo:block>
        <xsl:text disable-output-escaping="yes">&amp;#160;</xsl:text>
       </fo:block>
      </fo:table-cell>
     </fo:table-row>
     <fo:table-row>
      <fo:table-cell>
       <fo:block font-size="12pt" font="Arial" font-weight="bold"
space-after="5px">Tally Report</fo:block>
      </fo:table-cell>
     </fo:table-row>
    </fo:table-body>
   </fo:table>
  </fo:static-content>
<!-- End of header section.  Beginning of page footer -->
<fo:static-content flow-name="rptFooter">
<fo:block font-size="9pt" font-weight="normal">
 <fo:table table-layout="fixed" inline-progression-dimension="18cm"
cell-spacing="0" cell-padding="0">
  <fo:table-column column-width="4cm"/>
   <fo:table-column column-width="7.5cm"/>
    <fo:table-column column-width="2cm"/>
     <fo:table-column column-width="2cm"/>
      <fo:table-body>
       <fo:table-row>
        <fo:table-cell>
         <fo:block>
          <xsl:text disable-output-escaping="yes">&amp;#160;</xsl:text>
         </fo:block>
        </fo:table-cell>
       </fo:table-row>
       <fo:table-row>
        <fo:table-cell>
         <fo:block font-size="9pt" font="Arial" font-weight="normal"
text-align="left">
          <xsl:variable name="date">
           <xsl:value-of select="date:date-time()"/>
            </xsl:variable>
             <xsl:value-of select="substring($date,1,10)"/>
           </fo:block>
          </fo:table-cell>
          <fo:table-cell>
           <fo:block font="Arial" text-align="center" font-size="6pt"
font-weight="normal">
            <xsl:value-of select="report/AuditResponse/footerText"/>
          </fo:block>
         </fo:table-cell>
         <fo:table-cell>
          <fo:block font="Arial" text-align="right" font-size="9pt"
font-weight="normal">Page <fo:page-number/>
           / <fo:page-number-citation ref-id="last-page"/></fo:block>
          </fo:table-cell>
         </fo:table-row>
        </fo:table-body>
       </fo:table>
      </fo:block>
     </fo:static-content>
<!-- beginning of region body and beginning of Page Header information-->
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed" inline-progression-dimension="18cm"
cell-spacing="0" cell-padding="0">
 <fo:table-column column-width="6cm"/>
  <fo:table-column column-width="9cm"/>
   <fo:table-column column-width="3.5cm"/>
    <fo:table-body>
     <fo:table-row>
      <fo:table-cell>
       <fo:block font="Arial" font-size="9pt"
font-weight="bold">Customer:</fo:block>
       </fo:table-cell>
       <fo:table-cell>
        <fo:block font="Arial" font-size="9pt">
         <xsl:value-of select="report/audit/customername"/>
         </fo:block>
        </fo:table-cell>
       </fo:table-row>
        <fo:table-row>
         <fo:table-cell>
          <fo:block font-size="9pt" font="Arial"
font-weight="bold">Audit Location:</fo:block>
         </fo:table-cell>
          <fo:table-cell>
           <fo:block font="Arial" font-size="9pt">
            <xsl:value-of select="report/audit/levelstring"/>
           </fo:block>
          </fo:table-cell>
         </fo:table-row>
          <fo:table-row>
           <fo:table-cell>
            <fo:block font-size="9pt" font="Arial"
font-weight="bold">Audit Name:</fo:block>
           </fo:table-cell>
            <fo:table-cell>
             <fo:block font="Arial" font-size="9pt">
              <xsl:value-of select="report/audit/auditname"/>
             </fo:block>
            </fo:table-cell>
           </fo:table-row>
            <fo:table-row>
             <fo:table-cell>
              <fo:block font="Arial" font-size="9pt"
font-weight="bold">Audit Date:</fo:block>
             </fo:table-cell>
              <fo:table-cell>
               <fo:block font="Arial" font-size="9pt">
                <xsl:value-of select="report/audit/audit_date"/>
               </fo:block>
              </fo:table-cell>
             </fo:table-row>
              <fo:table-row>
               <fo:table-cell>
                <fo:block font-size="9pt" font="Arial"
font-weight="bold">User Account:</fo:block>
               </fo:table-cell>
                <fo:table-cell>
                 <fo:block font="Arial" font-size="9pt">
                  <xsl:value-of select="report/audit/user_name"/>
                </fo:block>
               </fo:table-cell>
              </fo:table-row>
               <fo:table-row>
                <fo:table-cell number-columns-spanned="4">
                 <fo:block border-bottom-style="solid"
border-top-style="thin" border-bottom-color="#000000"
border-top-color="#000000" border-bottom-width="thin"
border-top-width="thin" space-after="6px">
                  </fo:block>
                 </fo:table-cell>
                </fo:table-row>
                 <fo:table-row/>
                 <fo:table-row/>
           </fo:table-body>
   </fo:table>
   <!-- beginning of test section -->

   <fo:table table-layout="fixed" inline-progression-dimension="18cm"
cell-spacing="0" cell-padding="0">
    <fo:table-column column-width="8cm"/>
     <fo:table-column column-width="1cm"/>
      <fo:table-column column-width="2cm"/>
       <fo:table-column column-width="1.5cm"/>
        <fo:table-column column-width=".1cm"/>
         <fo:table-column column-width="1.5cm"/>
          <fo:table-body>
           <fo:table-row>
            <fo:table-cell>
             <fo:block font="Arial" text-align="left"
font-size="10pt" font-weight="bold" space-after="6px">
               Sections
             </fo:block>
            </fo:table-cell>

            <fo:table-cell>
             <fo:block font="Arial" text-align="center"
font-size="10pt" font-weight="bold" space-after="6px">
               List #
             </fo:block>
            </fo:table-cell>

            <fo:table-cell>
             <fo:block font="Arial" text-align="center"
font-size="10pt" font-weight="bold" space-after="6px">
               Response
             </fo:block>
            </fo:table-cell>

             <fo:table-cell>
              <fo:block font="Arial" text-align="center"
font-size="10pt" font-weight="bold" space-after="6px">
               Tally
              </fo:block>
              </fo:table-cell>
              <fo:table-cell/>

              <fo:table-cell>
              <fo:block font="Arial" text-align="center"
font-size="10pt" font-weight="bold" space-after="6px">
               CAR
              </fo:block>
             </fo:table-cell>
            </fo:table-row>
           </fo:table-body>
          </fo:table>


<fo:table table-layout="fixed" inline-progression-dimension="18cm" cell-spacing="0" cell-padding="0"> <fo:table-column column-width="8cm"/> <fo:table-column column-width="1cm"/> <fo:table-column column-width="2cm"/> <fo:table-column column-width="1.5cm"/> <fo:table-column column-width=".1cm"/> <fo:table-column column-width="1.5cm"/> <fo:table-body> <xsl:for-each select="report/audit/questions/question"> <xsl:sort data-type="number" select="sec_id"/> <xsl:sort data-type="number" select="sec_id"/> <xsl:sort data-type="number" select="sub_sec_id"/> <xsl:sort data-type="number" select="item_id"/> <fo:table-row> <xsl:choose> <xsl:when test="sec_id"> <xsl:variable name="test" select="sec_id"/> <xsl:if test="(sec_id &gt;=0) and sub_sec_id=0 and item_id=0 "> <fo:table-cell> <fo:block font="Arial" text-align="left" font-size="8pt" font-weight="normal" space-after="2px"> <xsl:value-of select="sec_id"/>-<xsl:value-of select="sub_sec_id"/>-<xsl:value-of select="item_id"/> <xsl:text disable-output-escaping="yes">&amp;#160;&amp;#160;&amp;#160;</xsl:text> <xsl:value-of select="itemdescription"/> </fo:block> </fo:table-cell> </xsl:if>


<!-- brings back a unique response number --> <fo:table-cell /> <fo:table-cell > <fo:block font="Arial" text-align="center" font-size="8pt" font-weight="normal" space-after="2px"> <xsl:if test="not(sec_id &gt;=0 and sub_sec_id &gt;=0 and item_id=0)"> <xsl:if test="sec_id=$test"> <fo:block></fo:block> <xsl:if test="not(audit_response/resp='')"> <xsl:for-each select="audit_response/resp[1][not(.=preceding::audit_response/resp[1])] | audit_response/resp[1][not(.=following::audit_response/resp[1])]"> <xsl:value-of select="../../resp_num"/> </xsl:for-each> </xsl:if> </xsl:if> </xsl:if> </fo:block> </fo:table-cell> <!--brings back unique responses -->

                  <fo:table-cell>
                   <fo:block font="Arial" text-align="center"
font-size="8pt" font-weight="normal" space-after="2px">
                    <xsl:choose>
                     <xsl:when test="sec_id">
                      <xsl:if test="not(audit_response/resp='')">
                       <xsl:if test="sec_id=$test">										
                        <xsl:for-each
select="audit_response/resp[1][not(.=preceding::audit_response/resp[1])]
| audit_response/resp[1][not(.=following::audit_response/resp[1])]">
                         <xsl:value-of select="."/>
                        </xsl:for-each>
                       </xsl:if>
                      </xsl:if>
                     </xsl:when>
                    </xsl:choose>										
                   </fo:block>							
                  </fo:table-cell>
<!-- brings back a tally of the responses -->

                 <xsl:variable name="group"
select="audit_response/resp[1][not(.=preceding::audit_response/resp[1])]
| audit_response/resp[1][not(.=following::audit_response/resp[1])]"/>

                   <fo:table-cell>
                   <fo:block font="Arial" text-align="center"
font-size="8pt" font-weight="normal" space-after="5px">
                    <xsl:if test="not(sec_id &gt;=0 and sub_sec_id
&gt;=0 and item_id=0)">
                     <xsl:if test="sec_id=$test">
                      <xsl:if test="$group != ''">
                       <xsl:choose> <!--begins the outside choose -->
                        <xsl:when test="sec_id">
                         <fo:block font="Arial" text-align="center"
font-size="8pt" font-weight="normal" space-after="5px">

                          <xsl:variable name="sec_id" select="sec_id"/>
                           <xsl:value-of
select="count(../question[sec_id =
$sec_id]/audit_response/resp[.=$group])"/>
                          </fo:block>
                         </xsl:when>
                        </xsl:choose>
                       </xsl:if>
                      </xsl:if>
                     </xsl:if>
                    </fo:block>
                   </fo:table-cell>



<!-- brings back a count of the cars per answered question -->

                 <fo:table-cell />
                  <fo:table-cell>
                   <fo:block font="Arial" text-align="center"
font-size="8pt" font-weight="normal" space-after="2px">
                     <xsl:if test="sec_id=$test">
                      <fo:block font="Arial" text-align="center"
font-size="8pt" font-weight="normal" space-after="2px">
                       <xsl:variable name="sec_id" select="sec_id"/>
                        <xsl:if test="sec_id=$sec_id">
                         <xsl:if
test="count(audit_response/corr_acts/corr_act/id[not(*)]) &gt;0">
                          <xsl:value-of
select="count(audit_response/corr_acts/corr_act/id[not(*)])"/>
                         </xsl:if>
                        </xsl:if>
                       </fo:block>
                      </xsl:if>
                     </fo:block>
                    </fo:table-cell>
                   </xsl:when>
                  </xsl:choose>
                 </fo:table-row>
                </xsl:for-each>
               </fo:table-body>
              </fo:table>


<fo:table table-layout="fixed" space-before="7px" border="1" border-style="solid" background-color="#EEEEEE" inline-progression-dimension="18cm" cell-spacing="0" cell-padding="0"> <fo:table-column column-width="8cm"/> <fo:table-column column-width="1cm"/> <fo:table-column column-width="2cm"/> <fo:table-column column-width="1.5cm"/> <fo:table-column column-width="2.5cm"/> <fo:table-column column-width=".5cm"/> <fo:table-body> <fo:table-row> <fo:table-cell> <fo:block font="Arial" text-align="left" font-size="10pt" font-weight="bold" space-after="6px"> Report Summary Totals: </fo:block> </fo:table-cell> <fo:table-cell/> <fo:table-cell> <fo:block font="Arial" text-align="right" font-size="10pt" font-weight="bold" space-after="6px"> Responses </fo:block> </fo:table-cell> <fo:table-cell> <fo:block font="Arial" text-align="center" font-size="10pt" font-weight="bold" space-after="6px"> Total </fo:block> </fo:table-cell> </fo:table-row> <fo:table-row> <fo:table-cell/> </fo:table-row> </fo:table-body> </fo:table> <!-- table to bring back the responses and car tallies--> <fo:table table-layout="fixed" border="1" border-style="solid" background-color="#99FFFF" inline-progression-dimension="18cm" cell-spacing="0" cell-padding="0"> <fo:table-column column-width="8cm"/> <fo:table-column column-width="1cm"/> <fo:table-column column-width="2cm"/> <fo:table-column column-width="1.5cm"/> <fo:table-column column-width="2.5cm"/> <fo:table-column column-width=".5cm"/> <fo:table-body> <fo:table-row> <fo:table-cell/> <fo:table-cell/> <fo:table-cell> <fo:block font="Arial" text-align="center" font-size="8pt" font-weight="normal" space-before = "5px" space-after="2px"> <xsl:for-each select="report/audit/questions/question[generate-id() = generate-id(key('response2',audit_response/resp)[1])]"> <xsl:if test="not(audit_response/resp='')"> <fo:block></fo:block> <xsl:value-of select="audit_response/resp"/> </xsl:if> </xsl:for-each> </fo:block> </fo:table-cell> <fo:table-cell> <fo:block font="Arial" text-align="center" font-size="8pt" font-weight="normal" space-after="2px" > <xsl:for-each select="report/audit/questions/question[count(.| key('response2', audit_response/resp)[1]) = 1]"> <xsl:if test="not(audit_response/resp='')"> <fo:block></fo:block> <xsl:if test="not(count(key('response2',audit_response/resp))=0)"> <xsl:value-of select="count(key('response2',audit_response/resp))"/> </xsl:if> </xsl:if> </xsl:for-each> </fo:block> </fo:table-cell> </fo:table-row> <fo:table-row> <fo:table-cell/> <fo:table-cell/> <fo:table-cell> <fo:block font="Arial" text-align="center" font-size="10pt" font-weight="bold" space-after="6px"> CARs </fo:block> </fo:table-cell> <!-- brings back a count of the cars per answered question --> <fo:table-cell> <fo:block font="Arial" text-align="center" font-size="8pt" font-weight="normal" space-after="2px"> <xsl:choose> <xsl:when test="/report/audit/questions/question"> <xsl:if test="not(audit_response/resp='')"> <xsl:if test="not(audit_response/corr_acts/corr_act='')"> <xsl:if test="not(audit_response/corr_acts/corr_act/id=0)"> <xsl:value-of select="count(//corr_act) div 2"/> </xsl:if> </xsl:if> </xsl:if> </xsl:when> </xsl:choose> </fo:block> </fo:table-cell> </fo:table-row> <!--end of CAR code --> </fo:table-body> </fo:table> <fo:block id="last-page"/> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> </xsl:stylesheet>

Current Thread