Reputation: 3017
I am new to xslt and am trying different options since few days. Am kind of out of ideas stuck with below scenario (more because of my lack of knowledge on xslt)
Input xml is something like:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MAIN>
<ProcessResponse>
<ORDERNO>workorder123</ORDERNO>
<NAME>BD-OC 102</NAME>
<FID>124</FID>
<FNO>57</FNO>
<AID>126</AID>
<BID>125</BID>
</ProcessResponse>
<ProcessResponse>
<ORDERNO>workorder123</ORDERNO>
<NAME>BD-OC 102</NAME>
<FID>125</FID>
<FNO>58</FNO>
<AID>127</AID>
<BID>128</BID>
</ProcessResponse>
<ProcessResponse>
<ORDERNO>workorder124</ORDERNO>
<NAME>BD-OC 102</NAME>
<FID>130</FID>
<FNO>59</FNO>
<AID>132</AID>
<BID>131</BID>
</ProcessResponse>
<ProcessResponse>
<ORDERNO>workorder124</ORDERNO>
<NAME>BD-OC 102</NAME>
<FID>132</FID>
<FNO>60</FNO>
<AID>133</AID>
<BID>134</BID>
</ProcessResponse>
</MAIN>
And the output I am expecting is something like (Basically I want every 2 consecutive elements to be merged into 1, merging the part that is not common). In procedural lang it should e simple but I tried recursive in xslt but did not get desired result.
Output after transformation:
<Response>
<Process>
<ORDERNO>workorder123</ORDERNO>
<NAME>BD-OC 102</NAME>
<F1>
<FID>124</FID>
<FNO>57</FNO>
<AID>126</AID>
<BID>125</BID>
</F1>
<F2>
<FID>125</FID>
<FNO>58</FNO>
<AID>127</AID>
<BID>128</BID>
</F2>
</Process>
<Process>
<ORDERNO>workorder124</ORDERNO>
<NAME>BD-OC 102</NAME>
<F1>
<FID>130</FID>
<FNO>59</FNO>
<AID>132</AID>
<BID>131</BID>
</F1>
<F2>
<FID>132</FID>
<FNO>60</FNO>
<AID>133</AID>
<BID>134</BID>
</F2>
</Process>
</Response>
Note: The actual files are much more complex than this but the basic Idea is the same, merge every 2 consecutive blocks into one (the common part).
Any help/Direction/Pointers appreciated.
Upvotes: 0
Views: 401
Reputation: 9627
To "merge the 2 consecutive rows" try this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="kOrderno" match="ProcessResponse" use="ORDERNO" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" >
<xsl:with-param name="ch" select="h1" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="ProcessResponse/ORDERNO"/>
<xsl:template match="ProcessResponse/NAME"/>
<xsl:template match="ProcessResponse/text()"/>
<xsl:template match="/*">
<Response>
<xsl:for-each select="ProcessResponse">
<xsl:if test="position() mod 2 = 1">
<Process>
<xsl:copy-of select="ORDERNO"/>
<xsl:copy-of select="NAME"/>
<xsl:variable name="on" select="ORDERNO" />
<xsl:element name="F1">
<xsl:apply-templates />
</xsl:element>
<xsl:element name="F2">
<xsl:apply-templates select="following-sibling::ProcessResponse[1]/*" />
</xsl:element>
</Process>
</xsl:if>
</xsl:for-each>
</Response>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 9627
Try this key based solution Using Keys to Group: The Muenchian Method:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="kOrderno" match="ProcessResponse" use="ORDERNO" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" >
<xsl:with-param name="ch" select="h1" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="ProcessResponse/ORDERNO"/>
<xsl:template match="ProcessResponse/NAME"/>
<xsl:template match="/*">
<Response>
<xsl:for-each select="ProcessResponse[count(. | key('kOrderno', ORDERNO)[1] ) =1] ">
<Process>
<xsl:copy-of select="ORDERNO"/>
<xsl:copy-of select="NAME"/>
<xsl:variable name="on" select="ORDERNO" />
<xsl:for-each select=" key('kOrderno', $on)" >
<xsl:element name="F{position()}">
<xsl:apply-templates ></xsl:apply-templates>
</xsl:element>
</xsl:for-each>
</Process>
</xsl:for-each>
</Response>
</xsl:template>
</xsl:stylesheet>
Which will generate the following output:
<?xml version="1.0"?>
<Response>
<Process>
<ORDERNO>workorder123</ORDERNO>
<NAME>BD-OC 102</NAME>
<F1>
<FID>124</FID>
<FNO>57</FNO>
<AID>126</AID>
<BID>125</BID>
</F1>
<F2>
<FID>125</FID>
<FNO>58</FNO>
<AID>127</AID>
<BID>128</BID>
</F2>
</Process>
<Process>
<ORDERNO>workorder124</ORDERNO>
<NAME>BD-OC 102</NAME>
<F1>
<FID>130</FID>
<FNO>59</FNO>
<AID>132</AID>
<BID>131</BID>
</F1>
<F2>
<FID>132</FID>
<FNO>60</FNO>
<AID>133</AID>
<BID>134</BID>
</F2>
</Process>
</Response>
Upvotes: 1