Reputation: 119
I have an XML that shows values with the field having the field values that looks like:
<data>
<currentRow>
<columnValue>usa</columnValue>
<columnValue>ma</columnValue>
<columnValue>boston</columnValue>
<columnValue>bob</columnValue>
</currentRow>
<currentRow>
<columnValue>usa</columnValue>
<columnValue>ma</columnValue>
<columnValue>boston</columnValue>
<columnValue>george</columnValue>
</currentRow>
<currentRow>
<columnValue>usa</columnValue>
<columnValue>ny</columnValue>
<columnValue>nyc</columnValue>
<columnValue>mary</columnValue>
</currentRow>
</data>
I want to generate an Xml producing that looks like
<Class>
<Student>
<Country>usa</Country>
<State>ma</State>
<City>boston</City>
<name>bob</name>
<name>george</name>
</Student>
<Student>
<Country>usa</Country>
<State>ny</State>
<City>nyc</City>
<name>mary</name>
</Student>
<Class>
In short, I have two questions:
Any ideas how do I do that?
Upvotes: 1
Views: 136
Reputation: 66723
The following stylesheet uses the Muenchian Method to group the currentRow
elements using the values of the first 3 columnValue
elements.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<!--Create a key grouping on the concatenated values of
country, state, and city separated by '-'-->
<xsl:key name="students-by-country-state-city"
match="currentRow"
use="concat(columnValue[1],
'-',
columnValue[2],
'-',
columnValue[3])"/>
<xsl:template match="data">
<Class>
<!--apply templates to the first item in each grouping of items -->
<xsl:apply-templates
select="currentRow[generate-id() =
generate-id(
key('students-by-country-state-city',
concat(columnValue[1],
'-',
columnValue[2],
'-',
columnValue[3]))[1]
)]"
/>
</Class>
</xsl:template>
<xsl:template match="currentRow">
<Student>
<Country>
<xsl:value-of select="columnValue[1]"/>
</Country>
<State>
<xsl:value-of select="columnValue[2]"/>
</State>
<City>
<xsl:value-of select="columnValue[3]"/>
</City>
<!-- find all of the names for this grouping -->
<xsl:for-each
select="key('students-by-country-state-city',
concat(columnValue[1],
'-',
columnValue[2],
'-',
columnValue[3]))/columnValue[4]">
<name>
<xsl:value-of select="."/>
</name>
</xsl:for-each>
</Student>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1