Page 1 of 1

How to express an Inner Join in XSLT?

Posted: Thu Apr 21, 2011 2:23 pm
by craigj
My source XML is as follows:

Code: Select all


<Data>
<Car registration="1" type="Ford" />
<Car registration="2" type="Volkswagen" />
<Car registration="3" type="Volkswagen" />
<Car registration="4" type="Porsche" />
<Car registration="5" type="Porsche" />
<Journey car="1" distance="10" />
<Journey car="1" distance="15" />
<Journey car="3" distance="5" />
<Journey car="2" distance="6" />
</Data>
I want to calculate 'The total distance covered by all Porsche cars'.

My query should look something like:

sum(/Data/Journey[SOMECONDITION]/@distance)

(where SOMECONDITION joins the journeys to the associated car and checks that @type = 'Porsche')

---

I'm just not quite sure of how to express this in XSLT. Any help would be appreciated.

Re: How to express an Inner Join in XSLT?

Posted: Thu Apr 21, 2011 2:32 pm
by craigj
Note: I realise the example source code I provided will produce a result of zero for 'Distance covered by all Porsche cars', but hopefully you get the idea.

The results would be:
Ford: 25
Volkswagen: 11
Porsche: 0

Re: How to express an Inner Join in XSLT?

Posted: Thu Apr 21, 2011 4:09 pm
by craigj
Ok, I managed to solve it using 2 lines:

Code: Select all


<xsl:variable name="volkswagenCars" select="/Data/Car[@type = 'Volkswagen']" />
<xsl:variable name="totalVolkswagenDistance" select="sum(/Data/Journey[@car = $volkswagenCars/@registration]/@distance)" />
Can this be expressed in one line?

Re: How to express an Inner Join in XSLT?

Posted: Thu Apr 21, 2011 4:36 pm
by sorin_ristache
Hello,

I don't think you can express it in one line if you want to process all the Car elements. For example:

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="Data">
<distances>
<xsl:for-each-group select="Car" group-by="@type">
<car type="{current-grouping-key()}" distance="{sum(for $i in current-group() return
following-sibling::Journey[@car = $i/@registration]/@distance)}"/>
</xsl:for-each-group>
</distances>
</xsl:template>
</xsl:stylesheet>

Regards,
Sorin

Re: How to express an Inner Join in XSLT?

Posted: Thu Apr 21, 2011 4:41 pm
by sorin_ristache
Actually the condition can be written as a single line (if you ignore the xsl:for-each-group element):

Code: Select all

  <xsl:for-each-group select="Car" group-by="@type">
<car type="{current-grouping-key()}" distance="{sum(following-sibling::Journey[@car = current-group()/@registration]/@distance)}"/>
</xsl:for-each-group>

Regards,
Sorin