Hi,
Though I have been working sometime with XSLT, I am having
trouble with this transformation. Anyone know how to do this?
The XML source is from a database and is really really huge
in size, so performance of the transformation is very critical...
<Root>
<Community>
<City>City1</City>
<A>
<B>
<Name>Name1</Name>
<Info>
<Detail no="100">Red</Detail>
</Info>
</B>
<B>
<Name>Name2</Name>
<Info>
<Detail no="200">Blue</Detail>
</Info>
</B>
<B>
<Name>Name3</Name>
<Info>
<Detail no="300">Green</Detail>
</Info>
</B>
</A>
</Community>
<Community>
<City>City2</City>
<A>
<B>
<Name>Name4</Name>
<Info>
<Detail no="100">Red</Detail>
</Info>
</B>
<B>
<Name>Name5</Name>
<Info>
<Detail no="200">Blue</Detail>
</Info>
</B>
<B>
<Name>Name6</Name>
<Info>
<Detail no="400">Yellow</Detail>
</Info>
</B>
</A>
</Community>
</Root>
This is the result I need to produce:
100, Red
City1
Name1
City2
Name4
200, Blue
City1
Name2
City2
Name5
300, Green
City1
Name3
400, Yellow
City2
Name6
Heres a stylesheet that will do it. It's a grouping problem, you just
need to group <Detail> elements by their id attibute and text content,
then apply templates to only the first one in the group. Check out
jeni's site for more on grouping http://www.jenitennison.com
(I've html like tags in the output rather than whitespace so my IDE can
tidy it for me :) You may want to replace the ancestor:: use with
another key to help performance)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="details" match="Detail" use="concat(@no,'/',.)"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="//Detail[generate-id() =
generate-id(key('details',concat(@no,'/',.))[1])]"/>
</root>
</xsl:template>
<xsl:template match="Detail">
<div detail="{concat(@no,', ',.)}">
<xsl:for-each select="key('details',concat(@no,'/',.))">
<span>
<xsl:value-of select="ancestor::Community/City"/>,<xsl:text/>
<xsl:value-of select="parent::Info/preceding-sibling::Name"/>
</span>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
cheers
andrew