Showing posts with label xslt xml xpath. Show all posts
Showing posts with label xslt xml xpath. Show all posts

Tuesday, 26 June 2007

Good use of xsl:key

This is a perfect example of how xsl:key can not only optimize the syntax of your xsl, but also its performance significantly.
In the following XML there are three separate nodesets, children of the same parent, that reference each other via different ids. The purpose of this exercise is to get a list of incidents for each car.

XML


<?xml version="1.0" encoding="UTF-8"?>
<root>
<car>
<CarInfo vin="4FL200212345">
<Owner>J. P. Morgan</Owner>
</CarInfo>
</car>
<car>
<CarInfo vin="3CL200212345">
<Owner>J.P. Thompson</Owner>
</CarInfo>
</car>
<carSpecifics vin="4FL200212345">
<CarMake xrefId="XREF12345">
<Color>Red</Color>
<Style>Sedan</Style>
</CarMake>
</carSpecifics>
<carSpecifics vin="3CL200212345">
<CarMake xrefId="XREF67890">
<Color>Red</Color>
<Style>Sedan</Style>
</CarMake>
</carSpecifics>
<CarXref xrefId="XREF12345">
<Incident>Friday Crash</Incident>
</CarXref>
<CarXref xrefId="XREF67890">
<Incident>Sat Crash</Incident>
</CarXref>
</root>


XSL

<xsl:key name="incidents"
match="/root//CarXref/Incident" use="../@xrefId"/>
<xsl:key name="carSpecifics"
match="/root/carSpecifics/CarMake/@xrefId" use="../../@vin"/>

<xsl:template match="/">
<incidents>
<xsl:apply-templates select="root/car/CarInfo/@vin"/>
</incidents>
</xsl:template>

<xsl:template match="@vin">
<xsl:apply-templates select="key('carSpecifics',.)"/>
</xsl:template>

<xsl:template match="@xrefId">
<xsl:apply-templates select="key('incidents', .)"/>
</xsl:template>

<xsl:template match="Incident">
<incident>
<xsl:value-of select="."/>
</incident>
</xsl:template>

Monday, 25 June 2007

Copying nodes depending on children values

The input XML needs to be refined to contain only nodes where the value element of a characteristics element where the name attibute is weight is greater than 15.

XML


<root>
<quality>
<batch id="1">
<characteristic name="weight">
<value>12</value>
</characteristic>
<characteristic name="length">
<value>45</value>
</characteristic>
<characteristic name="volume">
<value>67</value>
</characteristic>
</batch>
<batch id="2">
<characteristic name="weight">
<value>12</value>
</characteristic>
<characteristic name="weight">
<value>17</value>
</characteristic>
</batch>
<batch id="3">
<characteristic name="weight">
<value>56</value>
</characteristic>
<characteristic name="volume">
<value>65</value>
</characteristic>
</batch>
</quality>
</root>


XSL

<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/root">
<quality>
<xsl:copy-of select="
quality/batch[characteristic[@name= 'weight' and value &gt; 15]]
"/>
</quality>
</xsl:template>
</xsl:transform>

Friday, 22 June 2007

top id from xml


Clever little XPath 1.0, gets the node with the highest id value. Xpath 2.0 has the max() function that ultimately does the same thing.

/rt/item[@id[not(. &lt; ../../item/@id)]]


<rt>
<item id="1">txt</item>
<item id="2">txt</item>
<item id="5">txt</item>
<item id="4">txt</item>
</rt>


returns

<item id="5">txt</item>