Reputation: 11
I am transforming xml data to html page wiith the help of xslt . I want to eliminate duplicate data where appears like this in the following way .
<calendar>
<event>
<date>May 11</date>
<description>Mother's Day</description>
</event>
<event>
<date>May 12</date>
<description>Birthday</description>
</event>
<event>
<date>May 12</date>
<description>Board Meeting</description>
</event>
</calendar>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Event Dates </h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>date</th>
<th>description</th>
</tr>
<xsl:for-each select="calendar/event">
<tr>
<td><xsl:value-of select="date"/></td>
<td><xsl:value-of select="description"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
date description
May 11 Mother's Day
May 12 Birthday
May 12 Board Meeting
date description
May 11
Mother's Day
May 12
Birthday
Board Meeting
Please suggest me the XSLT code to modify . Thanks in advance .
Upvotes: 1
Views: 198
Reputation: 1796
The only way to solve your problem is a so called "Muenchian Grouping". Please refer to Muenchian Grouping - group within a node, not within the entire document which is pretty much the same as your question, only with names instead of days.
Upvotes: 0
Reputation: 243459
This short transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kDateByVal" match="date" use="."/>
<xsl:template match="/">
<xsl:text>date description</xsl:text>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match=
"date[generate-id()=generate-id(key('kDateByVal',.)[1])]">
<xsl:value-of select="concat('
',.)"/>
<xsl:for-each select="key('kDateByVal',.)">
<xsl:value-of select="concat('
',' ', ../description)"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
uses the classic Muenchian grouping method to transform the provided XML document:
<calendar>
<event>
<date>May 11</date>
<description>Mother's Day</description>
</event>
<event>
<date>May 12</date>
<description>Birthday</description>
</event>
<event>
<date>May 12</date>
<description>Board Meeting</description>
</event>
</calendar>
into the wanted, correct result:
date description
May 11
Mother's Day
May 12
Birthday
Board Meeting
Upvotes: 1
Reputation: 51
I found this solution and applied to your problem.
Jenni Tennison wrote a nice and short explanation of the method.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="text" indent="yes"/>
<xsl:key name="distinct-date" match="/calendar/event/date" use="./text()"/>
<xsl:template match="calendar">
<xsl:text>date description
</xsl:text>
<xsl:for-each select="event/date[generate-id(.) = generate-id(key('distinct-date',.)[1])]">
<xsl:value-of select="./text()"/>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="//event[date/text() = current()/text()]"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
<xsl:template match="event">
<xsl:text> </xsl:text><xsl:value-of select="description/text()"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1