Re: Ultimate arbitrary sort algorithm :-)

Subject: Re: Ultimate arbitrary sort algorithm :-)
From: Jeni Tennison <jeni.tennison@xxxxxxxxxxxxxxxx>
Date: Tue, 08 Aug 2000 11:54:44 +0100
Oliver,

>The following expression gives $string if $condition is true,
>otherwise it results in an empty string:
>   substring($string, 1 div number($condition))

Absolutely superb!  I've kept finding myself wanting conditions in XPaths,
and finally there is a way to do it.  This is obviously the 'Becker Method' :)

It is, of course, hideous when you actually use it.  You can make it a
little less hideous by dropping the number() - 'div' automatically converts
its arguments to a number anyway.  Do make sure, as well, to use boolean()
if the condition is a node set to convert it into a boolean value (true if
such a node exists, false if it doesn't).  In other words, the pattern is:

  concat(substring($result1,
                   1 div $condition1),
         substring($result2,
                   1 div $condition2),
         ...)

where the conditions are all boolean and the results are all strings.

Matt's original problem was:
>I have some data:
><item>MacBean</item>
><item>McBarlow</item>
><item>Re MacBart</item>
><item>Re McBeanie</item>
>
>Which needs to be sorted and transformed as follows:
><item>McBarlow</item>
><item>Re McBart</item>
><item>MacBean</item>
><item>Re McBeanie</item>

This is solved by:

<xsl:template match="list">
  <xsl:for-each select="item">
    <xsl:sort
      select="concat(
               substring(concat('Mac', substring-after(., 'Re Mc'), ', Re'),
		           1 div starts-with(., 'Re Mc')),
		 substring(concat(substring-after(., 'Re '), ', Re'),
		           1 div (starts-with(., 'Re ') and
                                not(starts-with(., 'Re Mc')))),
		 substring(concat('Mac', substring-after(., 'Mc')),
		           1 div (not(starts-with(., 'Re ')) and
                                starts-with(., 'Mc'))),
		 substring(.,
		           1 div not(starts-with(.,'Mc')
                                   or starts-with(., 'Re '))))" />
		<xsl:copy-of select="." />
	</xsl:for-each>
</xsl:template>

Assuming that 'Re ' is the only thing that can precede the name.  You can
nest the conditions if you want to (actually this makes it even more
complex!).

This is some of the ugliest XSLT I have ever seen :) :)

Cheers,

Jeni

Dr Jeni Tennison
Epistemics Ltd, Strelley Hall, Nottingham, NG8 6PE
Telephone 0115 9061301 ? Fax 0115 9061304 ? Email
jeni.tennison@xxxxxxxxxxxxxxxx



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


Current Thread