How to express an Inner Join in XSLT?

Here should go questions about transforming XML with XSLT and FOP.
craigj
Posts: 9
Joined: Thu Oct 29, 2009 1:51 pm

How to express an Inner Join in XSLT?

Post 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.
craigj
Posts: 9
Joined: Thu Oct 29, 2009 1:51 pm

Re: How to express an Inner Join in XSLT?

Post 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
craigj
Posts: 9
Joined: Thu Oct 29, 2009 1:51 pm

Re: How to express an Inner Join in XSLT?

Post 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?
sorin_ristache
Posts: 4141
Joined: Fri Mar 28, 2003 2:12 pm

Re: How to express an Inner Join in XSLT?

Post 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
sorin_ristache
Posts: 4141
Joined: Fri Mar 28, 2003 2:12 pm

Re: How to express an Inner Join in XSLT?

Post 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
Post Reply