Custom Sorting

Discussion in 'XML' started by Mike King, Jul 8, 2004.

  1. Mike King

    Mike King Guest

    Is there a way to sort by element names in XSLT, but not in ascending or
    descenting order but by elements that I specify?

    <root>
    <cat />
    <dog />
    <rabbit />
    </root>

    the sorted result tree

    <root>
    <rabbit />
    <cat />
    <dog />
    </root>
     
    Mike King, Jul 8, 2004
    #1
    1. Advertisements

  2. If I understand what you're trying to do, I believe you can do it in
    XSLT 1.0 if your processor supports exsl:node-set() or a similar
    extension (see www.exslt.org):

    <xsl:variable name="my-sort-order">
    <rabbit/>
    <cat/>
    <dog/>
    </xsl:variable>

    <xsl:template match="root">
    <xsl:for-each select="*">

    <xsl:sort select="count(exsl:node-set($my-sort-order)/*[name() =
    name(current())]/preceding-sibling::*)" data-type="number"
    order="ascending"/>

    <xsl:copy-of select="."/>

    </xsl:for-each>
    </xsl:template>
     
    Robin Johnson, Jul 10, 2004
    #2
    1. Advertisements

  3. Mike King

    Mike King Guest

    If I understand what you're trying to do, I believe you can do it in
    It worked! Thanks for your help.

    How did you come up with this solution? I'm having a difficult time with
    XSLT and I'm wondering how did you come up with this interesting solution.
    Does one need to read the XSLT spec or is there a real good book that
    explains XSLT. I consider myself a very technical person (I know several
    programming languages) but XSLT just kicks my butt. If no one answered my
    question, I was going to re-write my XSLT in C# or C++ to get the job the
    done. Thanks again for your help.
     
    Mike King, Jul 12, 2004
    #3
  4. [programmer-defined sort order in XSLT 1.0 using exsl:node-set()]
    Glad to hear it.
    A diseased mind and a lot of drugs. :)

    Tip 1: use exsl:node-set(). It makes XSLT *much* more powerful. In particular,
    it's the only way you can 'sweep' twice over the same bit of source XML, i.e.
    apply one template to a piece of the source, then apply a second template to
    the result of that first template (the tree-shaped result, not just its
    string-value.) The decision in the XSLT 1.0 spec not to allow XPath operations
    on a tree-fragment variable "to allow for this to be implemented in future
    versions" strikes me as truly bizarre. Thankfully XSLT 2.0 will do away with
    that. (XSLT 2.0 also has a programmer-defineable sort order construct, I
    believe. Michael Kay's Saxon at www.saxonica.com implements the current
    working draft of 2.0, but I'm shy of working drafts so I'm sticking with 1.0
    for the time being and using exsl:node-set a lot.)

    Tip 2: don't be afraid to do clever things that look inefficient. If your data
    is XML rather than strings, XSLT is *fast*. The only real exception I have
    found to this is that in both the implementations I have used (MSXML and
    Saxon), sweeping down the following-sibling:: axis is much faster than using
    preceding-sibling:: (e.g. when you're trying to find the first unique value of
    something - finding the last will be faster.)
    The lovely Michael Kay strikes again: "XSLT Programmer's Reference", in the
    "Programmer to Programmer" series by Wrox Press. The documentation on his site
    is also very helpful.
    "Assignment statement considered harmful."

    --
    Robin Johnson
    rj at robinjohnson dot f9 dot co dot uk
    http://www.robinjohnson.f9.co.uk

    Only joking about the drugs.
     
    Robin Johnson, Jul 13, 2004
    #4
  5. Mike King

    Ed Beroset Guest

    Fortunately, there's not (yet) a software patent on that technique.
    At the risk of posting a worthless "me too" post, I would absolutely
    second this. IMHO, it is one of the very few XSLT books worth the
    price. (I haven't yet found another, but my statement allows that one
    might exist.)
    Kay's corollary: "for-each usually a mistake"

    Ed
     
    Ed Beroset, Jul 16, 2004
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.