Connecting Tech Pros Worldwide Forums | Help | Site Map

XSLT grouping / xsl:key problem

Newbie
 
Join Date: Jun 2009
Posts: 1
#1: Jun 25 '09
Hi,

I have a problem with grouping. My source XML has <record> elements that have a @name and a @group attribute. It looks something like this:

Expand|Select|Wrap|Line Numbers
  1. <root>
  2.     <result>
  3.         <record name="test1" group="group1"><value>1A</value></record>
  4.         <record name="test2" group="group1"><value>1B</value></record>
  5.         <record name="test3" group="group1"><value>1C</value></record>
  6.         <record name="test1" group="group2"><value>2A</value></record>
  7.         <record name="test3" group="group2"><value>2F</value></record>
  8.         <record name="test4" group="group2"><value>2E</value></record>
  9.         <record name="test2" group="group3"><value>3A</value></record>
  10.         <record name="test3" group="group3"><value>3B</value></record>
  11.         <record name="test5" group="group3"><value>3E</value></record>
  12.     </result>
  13.     <result>
  14.         <record name="test1" group="group1"><value>1A</value></record>
  15.         <record name="test2" group="group1"><value>1B</value></record>
  16.         <record name="test3" group="group1"><value>1C</value></record>
  17.         <record name="test8" group="group4"><value>4D</value></record>
  18.         <record name="test9" group="group4"><value>4E</value></record>
  19.     </result>
  20. </root>
The goal is to have a html output, that shows the results as tables, one table per result which should look something like this:

---------------------------------------------
Result 1 | 1 | 2 | 3 |
---------------------------------------------
test1 | 1A | 2A | |
---------------------------------------------
test2 | 1B | | 3A |
---------------------------------------------
test3 | 1C | 2F | 3B |
---------------------------------------------
test4 | | 2E | |
---------------------------------------------
test5 | | | 3E |
---------------------------------------------

------------------------------------------------------
Result 2 | 1 | 2 | 3 | 4 |
------------------------------------------------------
test1 | 1A | | | |
------------------------------------------------------
test2 | 1B | | | |
------------------------------------------------------
test3 | 1C | | | |
------------------------------------------------------
test8 | | | | 4D |
------------------------------------------------------
test9 | | | | 4E |
------------------------------------------------------

For the numer of rows in the table I need to group the records by the @name attribute. I tried doing this with a <xsl:key>.

This is my XSLT stylesheet:

Expand|Select|Wrap|Line Numbers
  1. <xsl:key name="nameKey" match="record" use="@name"/>
  2. <xsl:template match="/">
  3.     <html>
  4.        <head>
  5.        </head>
  6.        <body>
  7.             <xsl:for-each select="root/result">
  8.                 <xsl:variable name="positionResult" select="position()"/>
  9.  
  10.                 <xsl:element name="table">
  11.                     <xsl:attribute name="border"><xsl:text>1</xsl:text></xsl:attribute>
  12.                     <xsl:element name="thead">
  13.                         <xsl:element name="tr">
  14.                             <xsl:element name="td">
  15.                                 <xsl:text>Result </xsl:text><xsl:value-of select="$positionResult"/>
  16.                             </xsl:element>
  17.                             <xsl:element name="td"><xsl:text>1</xsl:text></xsl:element>
  18.                             <xsl:element name="td"><xsl:text>2</xsl:text></xsl:element>
  19.                             <xsl:element name="td"><xsl:text>3</xsl:text></xsl:element>
  20.                             <xsl:element name="td"><xsl:text>4</xsl:text></xsl:element>
  21.                             <xsl:element name="td"><xsl:text>5</xsl:text></xsl:element>
  22.                         </xsl:element>
  23.                     </xsl:element>
  24.                     <xsl:element name="tbody">
  25.                         <xsl:for-each select="record[count(. | key('nameKey', @name)[1]) = 1]">
  26.                             <xsl:sort select="@name" order="ascending"/>
  27.                             <xsl:variable name="names" select="@name"/>
  28.  
  29.                             <xsl:element name="tr">
  30.                                 <xsl:element name="td"><xsl:value-of select="$names"/></xsl:element>
  31.                                 <xsl:element name="td"><xsl:value-of select="//result[$positionResult]/record[@name = $names and @group = 'group1']/value"/><xsl:text>*</xsl:text></xsl:element>
  32.                                 <xsl:element name="td"><xsl:value-of select="//result[$positionResult]/record[@name = $names and @group = 'group2']/value"/><xsl:text>*</xsl:text></xsl:element>
  33.                                 <xsl:element name="td"><xsl:value-of select="//result[$positionResult]/record[@name = $names and @group = 'group3']/value"/><xsl:text>*</xsl:text></xsl:element>
  34.                                 <xsl:element name="td"><xsl:value-of select="//result[$positionResult]/record[@name = $names and @group = 'group4']/value"/><xsl:text>*</xsl:text></xsl:element>
  35.                                 <xsl:element name="td"><xsl:value-of select="//result[$positionResult]/record[@name = $names and @group = 'group5']/value"/><xsl:text>*</xsl:text></xsl:element>
  36.                             </xsl:element>        
  37.  
  38.                         </xsl:for-each>
  39.                     </xsl:element>
  40.                 </xsl:element>
  41.             </xsl:for-each>
  42.         </body>
  43.     </html>
  44. </xsl:template>
Somehow however the resulting HTML does not show me the rows for test1, test2 and test3 for the second result table. Instead it looks like this:

------------------------------------------------------
Result 2 | 1 | 2 | 3 | 4 |
------------------------------------------------------
test8 | | | | 4D |
------------------------------------------------------
test9 | | | | 4E |
------------------------------------------------------

I think this is because the <xsl:key> for these has already been used in the first iteration ??! There is no way to predict the number of result elements in the source XML so I can't use a different <xsl:key> for each iteration...

Is there some other way to group the elements ?

Thank you very much !!

Leira

Reply


Similar XML bytes