RE: [xsl] Grouping using distinct-values

Subject: RE: [xsl] Grouping using distinct-values
From: "Ryan Graham" <Ryan.Graham@xxxxxxxxxxx>
Date: Thu, 3 Jul 2008 17:31:22 -0700
If I understood your problem correctly, this looks like a standard
for-each-group solution. First, group by the property_section_nm, then
iterate over the records in each group with a sort applied:

  <xsl:template match="table">
    <xsl:for-each-group select="record" group-by="column[@name =
'property_section_nm']">
      <xsl:value-of select="current-grouping-key()"/>
        <xsl:for-each select="current-group()">
          <xsl:sort select="column[@name='sort_order']"
data-type="number"/>
          <xsl:value-of
select="concat(column[@name='property_nm'],'=',column[@name='property_va
lue'])"/>
        </xsl:for-each>
    </xsl:for-each-group>
  </xsl:template>

This will operate on all table elements in your input, so you can limit
the scope of the processing as you enter the stylesheet if need be...

Hope this helps,
Ryan

-----Original Message-----
From: laker.gold@xxxxxxxxx [mailto:laker.gold@xxxxxxxxx]
Sent: Thursday, July 03, 2008 3:30 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] Grouping using distinct-values

Hi all,

Struggling with my understanding of grouping (and email clients...), in
spite of the excellent examples in the FAQ and archives -- sorry for my
thick-headedness.

Using xslt2 and saxon 9

XML is a terrible db dump:

<database>
    <table name="tbl_nm>
        <record>
        <column name="property_section_nm">[SECTION NAME 9]</column>
        <column name="property_type_id">10</column>
        <column name="property_type_nm">Common Property</column>
        <column name="property_nm">SERVICEURL_PRIMARY</column>
        <column name="sort_order">2</column>
        <column name="property_value">https://x.y.z.net/sd</column>
    </record>
        <record>
        <column name="property_section_nm">[SECTION NAME 2]</column>
        <column name="property_type_id">14</column>
        <column name="property_type_nm">some Property</column>
        <column name="property_nm">some name</column>
        <column name="sort_order">4</column>
        <column name="property_value">some value</column>
    </record>
        <record>
        <column name="property_section_nm">[SECTION NAME 9]</column>
        <column name="property_type_id">1</column>
        <column name="property_type_nm">random property</column>
        <column name="property_nm">another name</column>
        <column name="sort_order">4</column>
        <column name="property_value">another value</column>
    </record>
    <!-- many more records ... -->
    </table>
    <table name="tbl_nm2">
        <!-- many more records ... -->
    </table>
    <!-- many more tables ... -->
</database>

I need to write name=value pairs (name being the <column
name="property_nm"> and value being the <column name="property_value">
for all groups of column elements (or is it groups of record
elements??) in table name="tbl_nm" which share a like value for <column
name="property_section_nm">, sorted by the value of the column group's
<column name="sort_order">.

So, the expected result for the above xml would be something like:

[SECTION NAME 9]
SERVICEURL_PRIMARY=https://x.y.z.net/sd
another name=another value
[SECTION NAME 2]
some name=some value

My thinking has been that I'll write a for loop which will identify all
the distinct property_section_nm that I have, and pass each of the
distinct values in turn to a call-template which can then group across
the xml doc, and, in a for loop of it's own, sort and then output the
name=value pairs:

<xsl:for-each
select="distinct-values(record/column[@name='property_section_nm'])">
    <xsl:variable name="name" select="."/>
    <xsl:value-of select="$name"/>
    <xsl:text>
    </xsl:text>
    <xsl:call-template name="fred">
        <xsl:with-param name="nm">$name</xsl:with-param>
    </xsl:call-template>


<xsl:template name="fred">
    <xsl:param name="nm"/>
    <xsl:for-each-group
select="/database/table[@name='tbl_nm']/record[column[@name='property_se
ction_nm'
and .=$nm]]" group-by=".">
        <xsl:sort select="column[@name='sort_order']"
data-type="number"/>
        <xsl:value-of select="concat(column[@name='property_nm'], '=',
column[@name='property_value'])"/>
        <xsl:text>
        </xsl:text>
    </xsl:for-each-group>
</xsl:template>


but I'm getting an error message that my context item:
"/database/table[@name='tbl_nm']/record[column[@name='property_section_n
m'
and .=$nm]]"
isn't a node.  I've evaluated that xpath, without the variable name, and
it selects successfully...

Thanks for any hints

Edmund


This message is private and confidential. If you have received it in error,
please notify the sender and remove it from your system.

Current Thread