Search

Well then, here's a complicated one...

I have a datasource outputting products, with default prices. These prices can be overruled by offers and prices held in two other datasources.

My client wants to be able to sort results based on price. The price could be generated in the output by any of the three datasources in the order of default, price, offer.

As these are nodes from other datasources, how would I go about sorting using xsl:sort?

Is this a job for a custom datasource? I hope not, as it's already an ElasticSearch datasource...

I'm also thinking about something similar for streaming mixed social content. I'm not sure if you could do something clever with x-path axes?

<xsl:template match="/">
...
    <xsl:apply-templates select="data/set-one | data/set-two | data/set-three" mode="stream">
         <xsl:sort select="date/@iso" data-type="number" order="descending"/>
    </xsl:apply-templates>
...
</xsl:template>

<xsl:template match="*" mode="stream">
...
</xsl:template>    

Just an idea though, not even sure if apply-templates will accept those axes. If not it might be a case of using variables and exsl:node-set to join the data together.

Idea; not sure how it would work.

What if you used a recursive xslt function

Takes 6 parameters; the links to each datasource & current position.

In each loop you compare the prices of the first item(which are sorted in the DS I hope). And you output this item.

If the item was already listed you just call again with a +1 on the position for that parameter. basically a check in xpath should do the trick.

<xsl:variable name='already-done' select='$ds1/entry[@id=$selectedEntryId and position() &gt; $ds1-position]'

If its not been output before; output the value & do a + on the the param you want. Probably not the cleanest but simplest I can think of right now.

Otherwise you could always do something with keys but its not so neat. Or maybe a union datasource? but haven't used that in a while so not sure if you could sort & join.

You've lost me a bit there, but I think keys may be the answer here. I'll have to re-learn how to use them ;o)

What about JS if this is just presentation? http://www.allmyscripts.com/Table_Sort

You could do the sort method I noted earlier on a node-set from a variable which contained the logic for deciding which price to use.

Just switch the apply-templates select to exsl:node-set($variable) and include the exslt namespace?

Any reason this wouldn't work?

Did I misunderstand the requirement :D?

I'll post some xml in the morning, got to go to bed now -.-

John, search for "muenchian grouping" and you'll find what you need.
I always forget how it works, but it does :)

Here's some xml, very simplified, as I'm just making sure I explain myself properly:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <products>
        <entry id="1">
            <name>Test</name>
            <public-price>10.00</public-price>
            <trade-price>8.00</trade-price>
        </entry>
        <entry id="2">
            <name>Test</name>
            <public-price>10.00</public-price>
            <trade-price>8.00</trade-price>
        </entry>
        <entry id="3">
            <name>Test</name>
            <public-price>10.00</public-price>
            <trade-price>8.00</trade-price>
        </entry>
        <entry id="4">
            <name>Test</name>
            <public-price>10.00</public-price>
            <trade-price>8.00</trade-price>
        </entry>
        <entry id="5">
            <name>Test</name>
            <public-price>10.00</public-price>
            <trade-price>8.00</trade-price>
        </entry>
    </products>

    <prices>
        <entry id="6">
            <product>
                <item id="1">Test</item>
            </product>
            <public-price>15.00</public-price>
            <trade-price>14.00</trade-price>
        </entry>
        <entry id="7">
            <product>
                <item id="2">Test</item>
            </product>
            <public-price>12.00</public-price>
            <trade-price>11.00</trade-price>
        </entry>
        <entry id="8">
            <product>
                <item id="3">Test</item>
            </product>
            <public-price>18.00</public-price>
            <trade-price>15.00</trade-price>
        </entry>
    </prices>

    <offers>
        <entry id="9">
            <product>
                <item id="1">Test</item>
            </product>
            <public-offer-price>5.00</public-offer-price>
            <trade-offer-price>4.00</trade-offer-price>
        </entry>
        <entry id="10">
            <product>
                <item id="3">Test</item>
            </product>
            <public-offer-price>6.00</public-offer-price>
            <trade-offer-price>5.00</trade-offer-price>
        </entry>
        <entry id="11">
            <product>
                <item id="4">Test</item>
            </product>
            <public-offer-price>7.00</public-offer-price>
            <trade-offer-price>6.00</trade-offer-price>
        </entry>
    </offers>
</data>

Each product has a price. There are also prices that can override the products price, and then offers that can override those overriding prices.

There can be trade users or public users, but that's determined by a user type parameter, so I will need to be able to sort by either price.

There's probably a much more elegant way to do this but... xpathr 5098848

Actually you could refine the merge-prices template to select for trade or public price too then you wouldn't have to worry about the xsl:choose $user-type checks littering the place.

Ah bugger, just noticed the other price node which I didn't include in the template, however it's just another set of nested choose conditions within the merge-prices template to select for it.

It never occurred to me to do it like that, when I get a moment, I will put it into practice and get back to you.

Thanks very much for your insight guys!

Decent way; only problem I think; you're not 'sorting' items by value. If I understood that's what John wants. You're close though I'll see if I have a couple of minutes to spend on it shouldn't be too hard.

It's close enough for my sleepy brain to figure it out now, but thanks again!

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details