I'm very new to xslt and this is my first time posting to a Forum so please forgive me if I transgress any protocols.
I have to do a tally report. This report is divided up into sections. Each section has a list of questions. Each question has responses.
I need to display a list of responses to the questions (i.e. set:distinct), once and only once, each section.
My second problem is that these questions can also have corrective actions associated with them (CAR's in the report). The first section has 5 CAR's but when I do a sum I get the result 2-1-2 instead of 5.
This is a cut down version of the xml I'm working with (I have to use XSLT 1.0 transforming using FOP):
Expand|Select|Wrap|Line Numbers
- <?xml version="1.0" encoding="UTF-8" ?>
- <report>
- <audit>
- <auditid>159</auditid>
- <auditlevel_id>21</auditlevel_id>
- <levelstring>AUDIT LIBRARY</levelstring>
- <auditname>Cory</auditname>
- <cust_id>2</cust_id>
- <ld>1</ld>
- <li>8</li>
- <questions>
- <question>
- <id>13759</id>
- <sec_id>1</sec_id>
- <sub_sec_id>1</sub_sec_id>
- <item_id>1</item_id>
- <questiontype>SelectResponse</questiontype>
- <resp_num>3</resp_num>
- <itemdescription>Standard Action Test</itemdescription>
- <possible_score>10.00</possible_score>
- <score_criteria />
- <s_rs>
- <s_r>
- <seq>3</seq>
- <narr>Standard Action Test Narrative</narr>
- <followup>efdqde</followup>
- </s_r>
- </s_rs>
- <udf_info />
- <audit_response>
- <id>11602</id>
- <question_id>13759</question_id>
- <resp>N/a</resp>
- <narr>Standard Action Test Narrative</narr>
- <score>0.0</score>
- <p_o>0</p_o>
- <n_o>0</n_o>
- <p_f>0</p_f>
- <n_f>0</n_f>
- <question_type>SelectResponse</question_type>
- <answered>1</answered>
- <recordChanged>Y</recordChanged>
- <corr_acts>
- <corr_act>
- <id>1</id>
- </corr_act>
- <corr_act>
- <id>3</id>
- </corr_act>
- </corr_acts>
- </audit_response>
- ...
Expand|Select|Wrap|Line Numbers
- <?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="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: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">
- <fo:static-content flow-name="rptHeader" >
- <!-- beginning of region body and beginning of Page Header information-->
- <fo:flow flow-name="xsl-region-body" >
- <!-- 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:variable>
- <xsl:if test="(sec_id >=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">&#160;&#160;&#160;</xsl:text>
- <xsl:value-of select="itemdescription" />
- </fo:block>
- </fo:table-cell>
- </xsl:if>
- <fo:table-cell />
- <fo:table-cell >
- <!-- brings back a unique response number -->
- <fo:block font="Arial" text-align="center" font-size="8pt" font-weight="normal" space-after="2px">
- <xsl:if test="not(sec_id >=0 and sub_sec_id >=0 and item_id=0)" >
- <xsl:if test="sec_id=$test">
- <xsl:for-each select="/report/audit/questions/question[generate-id() = generate-id(key('response2',audit_response/resp)[1])]" />
- <fo:block></fo:block>
- <xsl:if test="not(audit_response/resp='')">
- <xsl:value-of select ="resp_num" />
- </xsl:if>
- </xsl:if>
- </xsl:if>
- </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:choose>
- <xsl:when test="sec_id">
- <xsl:if test="sec_id=$test">
- <xsl:if test="id=audit_response/question_id">
- <xsl:if test="not(audit_response/resp='')">
- <xsl:for-each select="/report/audit/questions/question[generate-id() = generate-id(key('response2',audit_response/resp)[1])]" />
- <xsl:variable name="groups"><xsl:value-of select="audit_response/resp" /></xsl:variable>
- <xsl:value-of select="exsl:node-set(set:distinct($groups))"/>
- <fo:block></fo:block>
- </xsl:if>
- </xsl:if>
- </xsl:if>
- </xsl:when>
- </xsl:choose>
- </fo:block>
- </fo:table-cell>
- <!-- brings back a tally of the responses -->
- <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 >=0 and sub_sec_id >=0 and item_id=0)" >
- <xsl:if test="sec_id=$test">
- <xsl:if test="not(audit_response/resp='')" >
- <xsl:for-each select="/report/audit/questions/question[generate-id() = generate-id(key('response2',audit_response/resp)[1])]" />
- <xsl:variable name="grouping"><xsl:value-of select="audit_response/resp" /></xsl:variable>
- <fo:block></fo:block>
- <xsl:value-of select="count($grouping)"/>
- </xsl:if>
- </xsl:if>
- </xsl:if>
- </fo:block>
- </fo:table-cell>
- <!-- brings back a count of the cars per answered question -->
- <xsl:choose>
- <xsl:when test="sec_id">
- <xsl:variable name="test" select="sec_id"></xsl:variable>
- <xsl:if test="(sec_id >=0) and sub_sec_id=0 and item_id=0 ">
- <fo:table-cell >
- <fo:block font="Arial" text-align="center" font-size="8pt" font-weight="bold" space-after="2px">
- <xsl:for-each select="/report/audit/questions/question">
- <xsl:if test="sec_id=$test">
- <xsl:variable name="trial"><number><xsl:value-of select="count(audit_response/corr_acts/corr_act[id])"/></number></xsl:variable>
- <xsl:if test="$trial >0">
- <fo:block></fo:block>
- <xsl:value-of select ="sum(exsl:node-set($trial)/number)"/>
- </xsl:if>
- </xsl:if>
- </xsl:for-each>
- </fo:block>
- </fo:table-cell>
- </xsl:if>
- </xsl:when>
- </xsl:choose>
- </xsl:when>
- </xsl:choose><!--ends the outside choose -->
- </fo:table-row>
- </xsl:for-each>
- </fo:table-body>
- </fo:table<fo:block id="last-page"/>
- </fo:flow>
- </fo:page-sequence>
- </fo:root>
- </xsl:template>
- </xsl:stylesheet>
Sections List# Response Tally CAR
1-0-0 words 3 N/a 1 2
1 Yes 1 1
1 No 1 2
1 No 1
2-0-0 1 Yes 1 1
1 No 1
1 Yes 1
This report should print No only once for section 1-0-0 with a count of two. It should print Yes only once for section 2-0-0 with a count of 2. It should print a total of 5 for the CAR's in section 1-0-0 and only 1 (as it does) for section 2-0-0.
Sorry this is such a long post.
Thanks
Debbie