Reputation: 21
Below is my Input xml and I want to use xslt 1.0 to transform into below specified xml.
Element ref needs to be used as key to merge and create the array in the output Input xml :
<Input>
<row>
<Name>ABC</Name>
<Ref>12345</Ref>
<Status>O</Status>
<Currency>USD</Currency>
<Date>2016-05-16</Date>
</row>
<row>
<Name>ABC</Name>
<Ref>12345</Ref>
<Status>O</Status>
<Currency>AUD</Currency>
<Date>2016-05-01</Date>
</row>
<row>
<Name>XYZ</Name>
<Ref>54321</Ref>
<Status>O</Status>
<Currency>AUD</Currency>
<Date>2016-03-01</Date>
</row>
<row>
<Name>XYZ</Name>
<Ref>54321</Ref>
<Status>O</Status>
<Currency>USD</Currency>
<Date>2016-05-01</Date>
</row>
</Input>
Output Xml: using the ref element in the request the there will be only two row elements in the output xml, but the values that are different are clubbed in a another sub node.
<Output>
<row>
<Name>ABC</Name>
<Ref>12345</Ref>
<Status>O</Status>
<Details>
<Detail>
<Currency>USD</Currency>
<Date>2016-05-16</Date>
</Detail>
<Detail>
<Currency>AUD</Currency>
<Date>2016-05-01</Date>
</Detail>
</Details>
</row>
<row>
<Name>XYZ</Name>
<Ref>54321</Ref>
<Status>O</Status>
<Details>
<Detail>
<Currency>AUD</Currency>
<Date>2016-03-01</Date>
</Detail>
<Detail>
<Currency>USD</Currency>
<Date>2016-05-01</Date>
</Detail>
</Details>
</row>
</Output>
Any help ?
Tried using the below xslt , but the if condition isn't working
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output method="xml" version="1.0"/>
<xsl:template match="/">
<xsl:element name="Output">
<xsl:apply-templates select="Input"/>
</xsl:element>
</xsl:template>
<xsl:template match="Input">
<xsl:for-each select="row">
<xsl:if test="(following-sibling::Ref = /Ref)">
<xsl:element name="row">
<xsl:element name="Name">
<xsl:value-of select="Name" />
</xsl:element>
<xsl:element name="Ref">
<xsl:value-of select="Ref" />
</xsl:element>
<xsl:element name="Status">
<xsl:value-of select="Status" />
</xsl:element>
<xsl:element name="Details">
<xsl:element name="Detail">
<xsl:element name="Currency">
<xsl:value-of select="Currency" />
</xsl:element>
<xsl:element name="Date">
<xsl:value-of select="Date" />
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2
Views: 1985
Reputation: 243469
This transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kRowByRefNameStat" match="row" use="concat(Name, '|', Ref, '|', Status)"/>
<xsl:template match="/*">
<Output>
<xsl:apply-templates select=
"row[generate-id()
=
generate-id(key('kRowByRefNameStat',
concat(Name, '|', Ref, '|', Status))[1])]"/>
</Output>
</xsl:template>
<xsl:template match="row">
<row>
<xsl:copy-of select="Name | Ref | Status"/>
<Details>
<xsl:apply-templates mode="inGroup" select=
"key('kRowByRefNameStat', concat(Name, '|', Ref, '|', Status))"/>
</Details>
</row>
</xsl:template>
<xsl:template match="row" mode="inGroup">
<Detail><xsl:copy-of select="Currency | Date"/></Detail>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<Input>
<row>
<Name>ABC</Name>
<Ref>12345</Ref>
<Status>O</Status>
<Currency>USD</Currency>
<Date>2016-05-16</Date>
</row>
<row>
<Name>ABC</Name>
<Ref>12345</Ref>
<Status>O</Status>
<Currency>AUD</Currency>
<Date>2016-05-01</Date>
</row>
<row>
<Name>XYZ</Name>
<Ref>54321</Ref>
<Status>O</Status>
<Currency>AUD</Currency>
<Date>2016-03-01</Date>
</row>
<row>
<Name>XYZ</Name>
<Ref>54321</Ref>
<Status>O</Status>
<Currency>USD</Currency>
<Date>2016-05-01</Date>
</row>
</Input>
produces the wanted, correct result:
<Output>
<row>
<Name>ABC</Name>
<Ref>12345</Ref>
<Status>O</Status>
<Details>
<Detail>
<Currency>USD</Currency>
<Date>2016-05-16</Date>
</Detail>
<Detail>
<Currency>AUD</Currency>
<Date>2016-05-01</Date>
</Detail>
</Details>
</row>
<row>
<Name>XYZ</Name>
<Ref>54321</Ref>
<Status>O</Status>
<Details>
<Detail>
<Currency>AUD</Currency>
<Date>2016-03-01</Date>
</Detail>
<Detail>
<Currency>USD</Currency>
<Date>2016-05-01</Date>
</Detail>
</Details>
</row>
</Output>
Explanation:
Muenchian grouping using composite-keys
Upvotes: 2