This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Grouping and Sorting on value inside group


Hi Peter,

I'm new to the thread, so I'm sorry if this has been mentioned before,
but I think that you can do:

<!-- index the data by local name -->
<xsl:key name="names" match="dataset/*/*" use="local-name()" />
<!-- index the data by id -->
<xsl:key name="ids" match="dataset/*/*" use="@dataid" />
<!-- index the data by name and id -->
<xsl:key name="names-and-ids" match="dataset/*/*/value"
         use="concat(local-name(), '+', @dataid)" />

and then:

  <!-- $sortcol holds the name of the column to sort by -->
  <xsl:variable name="sortcol" select="'data_x'" />
  
  <!-- $data holds the data within the document -->
  <xsl:variable name="data" select="//dataset/*/*" />

  <!-- $uniqueNames holds the first data elements with particular
       names -->
  <xsl:variable name="uniqueNames"
    select="$data[generate-id() =
                  generate-id(key('names', local-name())[1])]" />

  <!-- iterate over the data elements with unique ids -->
  <xsl:for-each
    select="$data[generate-id() =
                  generate-id(key('ids', @dataid)[1])]">
                  
    <!-- sort them based on the value of the data element with the
         same id and the $sortcol element name -->
    <xsl:sort
      select="key('ids', @dataid)[local-name() = $sortcol][1]/value" />

    <!-- $id holds the current id -->
    <xsl:variable name="id" select="@dataid" />

    <!-- iterate over the $uniqueNames in alphabetical order -->
    <xsl:for-each select="$uniqueNames">
      <xsl:sort select="local-name()" />

      <!-- create an element of that name -->
      <xsl:element name="{local-name()}">

        <!-- add a dataid attribute with the id -->
        <xsl:attribute name="dataid">
          <xsl:value-of select="$id" />
        </xsl:attribute>

        <!-- copy the value from the source data, if there is one -->
        <xsl:copy-of select="key('names-and-ids',
                                 concat(local-name(), '+', $id))" />
      </xsl:element>
    </xsl:for-each>
  </xsl:for-each>

---

In XSLT 2.0, you can do:
         
  <xsl:variable name="sortcol" select="'data_x'" />
  <xsl:variable name="data" select="//dataset/*/*" />
  <xsl:for-each-group select="$data" group-by="@dataid">
    <xsl:sort
      select="current-group()[local-name() = $sortcol]/value" />
    <xsl:variable name="id" select="@dataid" />
    <xsl:variable name="sameID" select="current-group()" />
    <xsl:for-each-group select="$data" group-by="local-name()">
      <xsl:sort select="local-name()" />
      <xsl:element name="{local-name()}">
        <xsl:attribute name="dataid">
          <xsl:value-of select="$id" />
        </xsl:attribute>
        <xsl:copy-of
          select="$sameID[local-name() =
                          local-name(current())]/value" />
      </xsl:element>
    </xsl:for-each-group>
  </xsl:for-each-group>

although it would probably be better to create a set of unique names
as above, with something like:

  <xsl:variable name="sortcol" select="'data_x'" />
  <xsl:variable name="data" select="//dataset/*/*" />
  <xsl:variable name="uniqueNames"
    select="distinct-values(for $d in $data
                            return local-name())" />
  <xsl:for-each-group select="$data" group-by="@dataid">
    <xsl:sort
      select="current-group()[local-name() = $sortcol]/value" />
    <xsl:variable name="id" select="@dataid" />
    <xsl:variable name="sameID" select="current-group()" />
    <xsl:for-each select="$uniqueNames">
      <xsl:sort select="." />
      <xsl:element name="{.}">
        <xsl:attribute name="dataid">
          <xsl:value-of select="$id" />
        </xsl:attribute>
        <xsl:copy-of
          select="$sameID[local-name() = current()]/value" />
      </xsl:element>
    </xsl:for-each>
  </xsl:for-each-group>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]