You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Jason Horman <ja...@jhorman.org> on 2002/11/26 06:58:09 UTC

[jelly] xpath sorting

I am attaching changes to ForEachTag and SetTag to support sorting. You may
have a better idea of how this should be implemented but I thought I would
send along my version anyhow.

The XPathComparator tries to determine if the strings being sorted are
numeric or not. You can force a type by specifiying the "sortDataType"
attribute, there is an example of this below. Descending sort is supported
via a "descending" attribute.

Also attached is a "xml:sort" tag which can sort lists of xml elements, such
as those returned via "xml:set".

Example XML:

            <a>
                <b v="3"/>
                <b v="2"/>
                <b v="1"/>
                <b v="11"/>
                <b v="1.4"/>
                <b v="1.2"/>
            </a>

Example Jelly:

        <j:set var="result" value=""/>
        <x:forEach select="$nums/a/b" var="x" sort="@v" descending="true">
            <x:set var="num" select="$x/@v"/>
            <j:set var="result" value="${result} ${num.get(0).getText()}"/>
        </x:forEach>

Example Deeper XML:

            <a>
                <b><c><d>3<e>1</e></d></c></b>
                <b><c><d>2<e>11</e></d></c></b>
                <b><c><d>1</d></c></b>
                <b><c><d>11</d></c></b>
            </a>

Example Jelly:

        <j:set var="result" value=""/>
        <x:forEach select="$deeper/a/b" var="x" sort="c/d">
            <j:set var="result" value="${result} ${x.getStringValue()}"/>
        </x:forEach>

        <!-- test sorting as strings instead of auto-detecting numbers -->
        <j:set var="result" value=""/>
        <x:forEach select="$nums/a/b" var="x" sort="@v"
sortDataType="java.lang.String">
            <x:set var="num" select="$x/@v"/>
            <j:set var="result" value="${result} ${num.get(0).getText()}"/>
        </x:forEach>

-jason horman
 jason@jhorman.org
 jhorman@musicmatch.com

Re: [jelly] xpath sorting

Posted by James Strachan <ja...@yahoo.co.uk>.
Thanks for your patch! Its applied in CVS now.


I did wonder about modifying the XPathComparator a touch and using the
number conversion features of XPath. Then from the sorting XPath you have
full control over whether XPaths should be sorted numerically or not via the
number() function. e.g.

<!-- sort in number order -->
<x:forEach select="$doc//foo" sort="number(@age)">
    ...


<!-- sort in alphabetical order -->
<x:forEach select="$doc//foo" sort="@age">
    ...

Using the algorithm that a String contains a dot in it seems sub-optimal
don't you think?

Since I committed your patch I've experimented and patched the
XPathComparator to use the  xpath.evaluate(node) method which if called for
the XPath "number(@age)" it would then return a number (typically a Double
as per the XPath 1.0 spec).

What do you think of this approach? It seems a bit cleaner to me. Also we
can then do things like sorting by the number of children (say).

<x:forEach select="//person" sort="count(child)">
    ...

or even more complex XPath expressions like:
    count(child)+(2 * count(child/child)) + @age

If you agree with this approach, we could descope the sortDataType attribute
and let XPath perform any type coercion as needed. If we ever need any more
type coercions (like Dates) we could just add a custom XPath function
instead to perform the conversions in the XPath engine

How's this sound with you? If you're happy to go with this, I'll commit my
patch to your committed patch.

James
-------
http://radio.weblogs.com/0112098/
----- Original Message -----
From: "Jason Horman" <ja...@jhorman.org>
To: <co...@jakarta.apache.org>
Sent: Tuesday, November 26, 2002 5:58 AM
Subject: [jelly] xpath sorting


> I am attaching changes to ForEachTag and SetTag to support sorting. You
may
> have a better idea of how this should be implemented but I thought I would
> send along my version anyhow.
>
> The XPathComparator tries to determine if the strings being sorted are
> numeric or not. You can force a type by specifiying the "sortDataType"
> attribute, there is an example of this below. Descending sort is supported
> via a "descending" attribute.
>
> Also attached is a "xml:sort" tag which can sort lists of xml elements,
such
> as those returned via "xml:set".
>
> Example XML:
>
>             <a>
>                 <b v="3"/>
>                 <b v="2"/>
>                 <b v="1"/>
>                 <b v="11"/>
>                 <b v="1.4"/>
>                 <b v="1.2"/>
>             </a>
>
> Example Jelly:
>
>         <j:set var="result" value=""/>
>         <x:forEach select="$nums/a/b" var="x" sort="@v" descending="true">
>             <x:set var="num" select="$x/@v"/>
>             <j:set var="result" value="${result}
${num.get(0).getText()}"/>
>         </x:forEach>
>
> Example Deeper XML:
>
>             <a>
>                 <b><c><d>3<e>1</e></d></c></b>
>                 <b><c><d>2<e>11</e></d></c></b>
>                 <b><c><d>1</d></c></b>
>                 <b><c><d>11</d></c></b>
>             </a>
>
> Example Jelly:
>
>         <j:set var="result" value=""/>
>         <x:forEach select="$deeper/a/b" var="x" sort="c/d">
>             <j:set var="result" value="${result} ${x.getStringValue()}"/>
>         </x:forEach>
>
>         <!-- test sorting as strings instead of auto-detecting numbers -->
>         <j:set var="result" value=""/>
>         <x:forEach select="$nums/a/b" var="x" sort="@v"
> sortDataType="java.lang.String">
>             <x:set var="num" select="$x/@v"/>
>             <j:set var="result" value="${result}
${num.get(0).getText()}"/>
>         </x:forEach>
>
> -jason horman
>  jason@jhorman.org
>  jhorman@musicmatch.com
>


----------------------------------------------------------------------------
----


> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>

__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>