XSL formatting sorting issues

Aidan Wilson aidan.wilson at unimelb.edu.au
Tue Mar 1 01:28:02 UTC 2011


Thanks for your help, John (et al.). I'll look into that for the de-suplication 
of reverse elements when I get time.

Tom Honeyman had a quicker solution for sorting the entire list of reverse 
elements with respect to each other, and not within sets of 'Words' elements, 
and that was to group the two <xsl:for-each together, so instead of:
<xsl:for-each select="Words[Status!='Exclude']">
 	<xsl:for-each select="Meanings/Reverse">
I now have just:
<xsl:for-each select="Words[Status!='Exclude']/Meanings/Reverse">

The way I had it meant I was selecting each word, and within that set, each 
Reverse element, which was where the sort was having trouble. This selection 
now works brilliantly.

-Aidan

On Mon, 28 Feb 2011, John Mansfield wrote:

> Hi Aidan,
> I will try to help. First I'll discuss your issue about sorting according to
> Reverse elements, then secondly I'll address your "ideal" solution of not
> duplicating identical Reverse elements.
> 
> 1. If you want to have all the Reverse elements in the source sorted as a
> single list, rather than a series of sorted lists, one for each Headword,
> then I think your problem is that you are doing your sort inside this
> for-each loop:
>       <xsl:for-each select="Words[Status!='Exclude']">
> 
> So you need a template structure that goes directly from the
> whole-dictionary level right to the Reverse elements, rather than getting to
> them via the Words wrappers. Does that make sense? 
> Maybe something like:
> 
> <xsl:template match="Dictionary">
>   <xsl:for-each select="//Reverse">
>     <xsl:sort select="."/>
>     <p><b><xsl:value-of select="."/></b></p>
>     <xsl:value:of select="ancestor::Words/Headword"/>
>   </xsl:for-each>
> </xsl:template>
> 
> PS: another way of sorting in xsl is with an attribute @order-by on the
> <for-each element. I don't know what the difference is between the methods,
> and it may be arcane.
> 
> 
> 2. As for de-duplicating the Reverse elements: I don't think XSL is a
> particularly good tool for it; it's not a very good framework for comparing
> strings... and when you want to extract wordlists from data, you often get
> sets of things that are not identical character-by-character, but you would
> like to have treated as one.
> 
> That said, it might work if you have a condition, simply asking at each
> Reverse element, "have I already displayed a Reverse element like this one?"
> And if not, then display it, but alongside display not just it's own
> Headword sibling, but the Headwords of each Reverse elements with that
> value.
>   Code could be something like this:
> 
> <xsl:template match="Dictionary">
>   <xsl:for-each select="//Reverse">
>     <xsl:sort select="."/>
>     <!-- I'm not sure if you need this variable, but you might need it for
> the output bit below-->
>     <xsl:variable name="this_word" select="."/>
>     <xsl:choose>
>       <xsl:when test="$this_word =
> ancestor::Words/preceding-sibling::Words//Reverse">
>           <!-- no output - we've seen this Reverse before -->
>       </xsl:when>
>       <xsl:otherwise>
>          <!-- output the Reverse element -->
>          <p><b><xsl:value-of select="."/></b></p>
>          <!-- for each Words element that has this Reverse word in it,
> output the Headword -->
>          <xsl:for-each
> select="ancestor::Words/preceding-sibling::Words[descendent::Reverse =
> $this_word]
> or ancestor::Words/following-sibling::Words[descendent::Reverse =
> $this_word]">
>              <xsl:value:of select="Headword"/>
>          </xsl:for-each>
>       </xsl:otherwise>
>   </xsl:for-each>
> </xsl:template>
> 
> I don't know if that will work, but it seems like it should.
> 
> j
> 
> On 28 February 2011 15:30, Aidan Wilson <a.wilson at pgrad.unimelb.edu.au>
> wrote:
>       Hi RNLDers (I still prefer "Ronaldos")
>
>       Does anyone have fairly good XSL skills and could guide me
>       through a particularly nasty dictionary formatting issue?
>
>       The problem is that I have a reverse word finder which is built
>       by extracting an element from each headword ('Reverse' which was
>       originally put in for exactly this purpose). Here's an example
>       of a word's XML (totally made up
>       example to demonstrate the point):
>
>       <Words>
>        <Headword>elevate</Headword>
>        <Category>verb</Category>
>        <Meanings>
>          <Definition>to raise, to lift</Definition>
>          <Reverse>raise</Reverse>
>          <Reverse>lift</Reverse>
>          <Examples>
>            <Example>You need to elevate your blood pressure</Example>
>            <Translation>You need to raise your blood
>       pressure</Translation>
>          </Examples>
>        </Meanings>
>       </Words>
>
>       The difficulty is that some words will have more than one
>       Reverse element (as above). At the moment I can either:
>       a) Extract only the first reverse element from each entry,
>       display it next to the headword, and all will be in alphabetical
>       order by the Reverse element, or
>       b) Extract all reverse elements from all headwords, and display
>       each one next to its headword, but they will be ordered *within
>       the set of reverse elements of that word.
>
>       What I mean by that, is that I can get it working so I can
>       produce:
>
>       Lift:
>        elevate
>
>       Raise:
>        elevate
>
>       But the Reverse elements from any other words will be sorted
>       amongst themselves, but independently of any other word. So what
>       I get in my English to Wagiman section is essentially ordered by
>       the Wagiman word, but each word's
>       English glosses sorted among themselves.
>
>       What I would like is to pair each reverse element with its
>       headword and then sort the whole list for the whole dictionary
>       at once.
>
>       Ideally, actually, I'd like to group together identical Reverse
>       elements so that I could have something like:
>
>       Lift:
>        boost
>        elevate
>        heighten
>        raise
>
>       Instead of listing them separately.
>
>       Here's the relevant section of my xsl stylesheet:
>
>       <xsl:for-each select="Words[Status!='Exclude']">
>              <xsl:sort select="Meanings/Reverse"/>
>              <xsl:for-each select="Meanings/Reverse">
>                      <p><strong><xsl:value-of
>       select="."/></strong><br/>
>                      <xsl:value-of select="../../Headword"/></p>
>              </xsl:for-each>
>       </xsl:for-each>
>
>       Hopefully this isn't an impossible task. And hopefully someone
>       knows more than my week's worth of xsl and can point me in the
>       right direction!
>
>       --
>       Aidan Wilson
>
>       PhD Candidate
>       Dept of Linguistics and Applied Linguistics
>       The University of Melbourne
>
>       +61428 458 969
>       a.wilson at pgrad.unimelb.edu.au
> 
> 
> 
>


More information about the Resource-network-linguistic-diversity mailing list