Tuesday, 10 February 2015

Nested grouping using XSLT muenchian-grouping



I had to group a xml document in xslt 1.0 using Oracle Service Bus.


This is the sample input file(Simplified):



<?xml version="1.0" encoding="UTF-8"?>
<EMailData>
<property name="A">
<property name="B">
<property name="C">
<row>
<property name="C1">
<value>ValC1</value>
</property>
<property name="C2">
<value>ValC2</value>
</property>
<property name="C3">
<value>Valc3</value>
</property>
<property name="C4">
<value>Valc4</value>
</property>
</row>
</property>
<property name="C">
<row>
<property name="C1">
<value>ValC1</value>
</property>
<property name="C2">
<value>ValC2</value>
</property>
<property name="C3">
<value>Valc3</value>
</property>
<property name="C4">
<value>Valc4</value>
</property>
</row>
</property>
<property name="D">
<row>
<property name="D1">
<value>ValD1</value>
</property>
<property name="D2">
<value>VALd2</value>
</property>
<property name="D3-InnerElement"> //Need to Group this too
<row>
<property name="Status">
<value>Status122</value>
</property>
</row>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status123</value>
</property>
</row>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status124</value>
</property>
</row>
</property>
</row>
</property>
<property name="D">
<row>
<property name="D1">
<value>ValD1</value>
</property>
<property name="D2">
<value>VALd2</value>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status122</value>
</property>
</row>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status123</value>
</property>
</row>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status124</value>
</property>
</row>
</property>
</row>
</property>
</property>
</property>
</EMailData>


My XSLT Logic:



<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://ift.tt/tCZ8VR">

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:key name="group" match="/*/*/*/property" use="@name"/>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="/*/*/*[property[@name]]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each select="*[generate-id() = generate-id(key('group', @name)[1])]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="key('group', @name)/*"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>

<!--Change for Inner Hierarchy-->

<xsl:key name="inner-group" match="/*/*/*/property" use="@name"/>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="/*/*/*[property[@name]]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each select="*[generate-id() = generate-id(key('inner-group', @name)[1])]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="key('inner-group', @name)/*"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>


Anticipated o/p



<?xml version="1.0" encoding="UTF-8"?>
<EMailData>
<property name="A">
<property name="B">
<property name="C">
<row>
<property name="C1">
<value>ValC1</value>
</property>
<property name="C2">
<value>ValC2</value>
</property>
<property name="C3">
<value>Valc3</value>
</property>
<property name="C4">
<value>Valc4</value>
</property>
</row>
<row>
<property name="C1">
<value>ValC1</value>
</property>
<property name="C2">
<value>ValC2</value>
</property>
<property name="C3">
<value>ValC3</value>
</property>
<property name="C4">
<value>Valc4</value>
</property>
</row>
</property>
<property name="D">
<row>
<property name="D1">
<value>ValD1</value>
</property>
<property name="D2">
<value>VALd2</value>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status122</value>
</property>
</row>
<row>
<property name="Status">
<value>Status123</value>
</property>
</row>
<row>
<property name="Status">
<value>Status124</value>
</property>
</row>
</property>
</row>
<row>
<property name="D1">
<value>ValD1</value>
</property>
<property name="D2">
<value>ValD2</value>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status133</value>
</property>
</row>
<row>
<property name="Status">
<value>Status134</value>
</property>
</row>
</property>
</row>
</property>
</property>
</property>
</EMailData>


But The D3-innerelement is not grouped. Tell me Where I went wrong!!


o/p For my XSLT



<?xml version="1.0" encoding="UTF-8"?>
<EMailData>
<property name="A">
<property name="B">
<property name="C">
<row>
<property name="C1">
<value>ValC1</value>
</property>
<property name="C2">
<value>ValC2</value>
</property>
<property name="C3">
<value>Valc3</value>
</property>
<property name="C4">
<value>Valc4</value>
</property>
</row>
<row>
<property name="C1">
<value>ValC1</value>
</property>
<property name="C2">
<value>ValC2</value>
</property>
<property name="C3">
<value>Valc3</value>
</property>
<property name="C4">
<value>Valc4</value>
</property>
</row>
</property>
<property name="D">
<row>
<property name="D1">
<value>ValD1</value>
</property>
<property name="D2">
<value>VALd2</value>
</property>
<property name="D3-InnerElement"> //Need to Group this too
<row>
<property name="Status">
<value>Status122</value>
</property>
</row>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status123</value>
</property>
</row>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status124</value>
</property>
</row>
</property>
</row>
<row>
<property name="D1">
<value>ValD1</value>
</property>
<property name="D2">
<value>VALd2</value>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status122</value>
</property>
</row>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status123</value>
</property>
</row>
</property>
<property name="D3-InnerElement">
<row>
<property name="Status">
<value>Status124</value>
</property>
</row>
</property>
</row>
</property>
</property>
</property>
</EMailData>


Thanks in Advance!


No comments:

Post a Comment