Print

Print


Hello Michele, 

Michele R Combs on Thursday 07 February 2008 16:31:

> Let's say I have the following data (forgive the inanely simple
> placeholder content!!) :

> <c0x>...<unittitle>Apple, still
> life</unittitle><origination>Picasso</origination>...</c0x>
> <c0x>...<unittitle>Baby, still life</unittitle><origination>Fra
> Angelico</origination>...</c0x>
> <c0x>...<unittitle>Chair, still
> life</unittitle><origination>Picasso</origination>...</c0x>
> <c0x>...<unittitle>Duck, still
> life</unittitle><origination>Michelangelo</origination>...</c0x>
> <c0x>...<unittitle>Elephant, still
> life</unittitle><origination>Holbein</origination>...</c0x>
> <c0x>...<unittitle>Frog, still
> life</unittitle><origination>Michelangelo</origination>...</c0x>
> <c0x>...<unittitle>Giraffe, still
> life</unittitle><origination>Holbein</origination>...</c0x>
> <c0x>...<unittitle>Horse, still
> life</unittitle><origination>Picasso</origination>...</c0x>

> I want to generate a listing in alpha order by originator, with the
> titles in alpha order underneath that, but I don't want to repeat the
> originator name -- e.g. I want it to look like this:

> Fra Angelico
>      Baby, still life
> Holbein
>      Elephant, still life
>      Giraffe, still life
> Michelangelo
>      Duck, still life
>      Frog, still life
> Picasso
>      Apple, still life
>      Chair, still life
>      Horse, still life
> 
> I've got the list sorted the way I want (first on originator, then on
> unittitle) via an xsl:sort inside a for-each, but I can't seem to find a
> way to show the author's name only once when I for-each through it.
> I've tried checking the preceding <originator> against the current one,
> but it apparently checks the preceding one in original document order,
> not in the sorted-set order.  Any ideas?  So far I'm stumped but I can't
> believe it's this hard!  



supposing
<c01><did>
  <unittitle>Duck, still life</unittitle>
  <origination>Michelangelo</origination>
</did></c01>


In XSLT 2.0 you might use


  <xsl:for-each-group select="/ead/archdesc/dsc/c01/did" group-by="origination">
    <xsl:sort select="current-grouping-key()"/> 
    <xsl:text>&#xA;&#xA;</xsl:text>
    <xsl:value-of select="origination" />
    <xsl:for-each-group select="current-group()" group-by=".">
      <xsl:sort select="unittitle"/> 
      <xsl:text>&#xA;&#x9;</xsl:text>
      <xsl:value-of select="unittitle" />
    </xsl:for-each-group>
  </xsl:for-each-group>
  <xsl:text>&#xA;&#xA;</xsl:text>



Not very hip on me keys, but in XSLT 1.0 you might try Muenchian grouping. 

<xsl:key name="painter" match="did" use="origination" />

<xsl:template match="/">
  <xsl:text>&#xA;&#xA;</xsl:text>
  <xsl:for-each select="/ead/archdesc/dsc/c01/did[generate-id(.) = 
                generate-id(key('painter', origination)[1])]">
    <xsl:sort select="origination"/> 
    <xsl:value-of select="origination" />
    <xsl:for-each select="key('painter', origination)">
      <xsl:sort select="unittitle"/>
      <xsl:text>&#xA;&#x9;</xsl:text>
      <xsl:value-of select="unittitle" />
    </xsl:for-each>
    <xsl:text>&#xA;</xsl:text>
  </xsl:for-each>
  <xsl:text>&#xA;&#xA;</xsl:text>
</xsl:template>



Regards, Dirk