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: Sorting Question: Muenchian method? Substring in Key?


--- Thomas_M <Thomas_M at bls dot gov> wrote:

 
> Hello. This is my first XSLT project. I'm having trouble with
> grouping
> sorted items (seems to be a common theme). I have a XML file like
> this
> (simplified):
> 
> <topics>
>   <topic>Anteater</topic>
>   <topic>Aardvark</topic>
>   <topic>Beetle, Smaller European Elm Bark</topic>
>   <topic>Beetle, American Burying</topic>
>   <topic>Chimpanzee</topic>
> </topics>
> 
> I would like the output to be sorted and grouped, with each group
> getting a
> heading:
> 
> A
> Aardvark
> Anteater
> 
> B
> Beetle, American Burying
> Beetle, Smaller European Elm Bark
> 
> C
> Chimpanzee
> 
> The corresponding part of my XSL is below.
> 
>   <xsl:template match="topics">
>    <table border="1">
>       <xsl:for-each select="topic">
>         <xsl:sort select="."/>
>         <xsl:variable name="previndex" select="position()-1"/>
>         <xsl:if test="not(substring(.,1,1)
>                       = substring(/topics/topic[$previndex],1,1))">
> 		<tr><th><xsl:value-of select="substring(.,1,1)"/></th></tr>
> 
>         </xsl:if>
>             <tr>
>               <td><xsl:value-of select="."/></td>
>             </tr>
>       </xsl:for-each>
>     </table>
>   </xsl:template> 
> 
> As you can see, I'm comparing an element in a sorted node-set with a
> document-order node-set. This works only if the XML is pre-sorted. Is
> there
> a way to create the sorted node-set first, so that I can both
> traverse
> and
> use it in my test?
> 
> I have seen a few examples of the Muenchian method, and it would seem
> this
> is another (perhaps better) way solve my problem. However, I've tried
> several times to implement it and can't seem to get it right (can you
> use a
> substring in a key?)
> 
> Thanks for any insight,
> 
> - Mark.


Hi Mark,

Yes, the use of the Muenchian method to solve your problem is very
straightforward:

source xml (the one provided by you, but reshuffled):
---------------------------------------------------
<topics>
  <topic>Chimpanzee</topic>
  <topic>Aardvark</topic>
  <topic>Beetle, Smaller European Elm Bark</topic>
  <topic>Anteater</topic>
  <topic>Beetle, American Burying</topic>
</topics>

stylesheet:
----------
<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 
  <xsl:output method="text"/>
  
  <xsl:variable name="NL" select="'&#xA;'"/>

  <xsl:key name="kTopic" match="topic" use="substring(.,1,1)"/>

  <xsl:template match="/">
    <xsl:for-each select="/*/topic
                              [
                               generate-id()
                              =
                               generate-id(key('kTopic',
                                               substring(.,1,1) 
                                               )[1]
                                           )
                              ]">
      <xsl:sort select="substring(.,1,1)"/>
      
      <xsl:value-of select="concat($NL, substring(.,1,1))"/>
      
      <xsl:for-each select="key('kTopic',substring(.,1,1))">
        <xsl:value-of select="concat($NL, .)"/>        
      </xsl:for-each>
      <xsl:value-of select="$NL"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Result:
-------

A
Aardvark
Anteater

B
Beetle, Smaller European Elm Bark
Beetle, American Burying

C
Chimpanzee


Hope this helped.





=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
New DSL Internet Access from SBC & Yahoo!
http://sbc.yahoo.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]