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: Problem with grouping


Hi Bjorn,

> I have a problem with the use of the meunchian method for grouping.
> The problem is that, within the items that I want to group can
> belong to more than one group and I also want them to be listed in
> all valid groups. The stylesheet that I have now lists each item in
> only one group.

The secret here is in the definition of the key. When you do grouping
with keys you need a 1:1 correspondence between the node that you
match and the value it has. With the key as you have it:

> <xsl:key name="applicability" match="ink"
>          use="applicability/item/@model" />

you have a 1:many correspondence -- each ink element has many models.

Instead, use the key to index the items by their model, as follows:

<xsl:key name="models" match="item" use="@model" />

Then use that key to identify the unique models:

<xsl:template match="inks">
  <xsl:for-each select="ink/applicability/item
                          [generate-id() =
                           generate-id(key('models', @model)[1])]">
    <xsl:sort select="@model" />
    <h1><xsl:value-of select="@model" /></h1>
    ...
  </xsl:for-each>
</xsl:template>

To find the ink types, you can get a list of all the item elements for
that particular model, and travel from them up the node tree to their
ink ancestor, and from there down to its type element child:

<xsl:template match="inks">
  <xsl:for-each select="ink/applicability/item
                          [generate-id() =
                           generate-id(key('models', @model)[1])]">
    <xsl:sort select="@model" />
    <h1><xsl:value-of select="@model" /></h1>
    <xsl:for-each select="key('models', @model)/ancestor::ink">
      <xsl:sort select="type" />
      <div><xsl:apply-templates select="type" /></div>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

---

The same logic applies in XSLT 2.0:

<xsl:template match="inks">
  <xsl:for-each-group select="ink/applicability/item"
                      group-by="@model">
    <xsl:sort select="@model" />
    <h1><xsl:value-of select="@model" /></h1>
    <xsl:for-each select="current-group()/ancestor::ink">
      <xsl:sort select="type" />
      <div><xsl:apply-templates select="type" /></div>
    </xsl:for-each>
  </xsl:for-each-group>
</xsl:template>

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]