XML node merging using XSLT
Is it possible to combine elements using XSLT.
If I have the following XML
<data> <item column="left" value="1" /> <item column="left" value="2" /> <item column="right" value="3" /> <item column="left" value="4" /> <item column="right" value="5" /> <item column="right" value="6" /> <item column="right" value="7" /> <item column="left" value="8" /> <item column="right" value="9" /> <item column="right" value="10" /> </data> I need the following output:
<data> <item left="1" right="3 /> <item left="2" right="5" /> <item left="4" right="6" /> <item left="8" right="7" /> <item left="" right="9" /> <item left="" right="10" /> </data> But I have no idea if this is possible using XSLT
This conversion is:
<xsl: stylesheet version = "1.0"
xmlns: xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl: output omit-xml-declaration = "yes" indent = "yes" />
<xsl: template match = "data">
<xsl: variable name = "vNumLeft" select = "count (item [@ column = 'left'])" />
<data>
<xsl: apply-templates select = "* [@ column = 'left']" />
<xsl: apply-templates select =
"* [@ column = 'right'] [position ()> $ vNumLeft]" />
</data>
</ xsl: template>
<xsl: template match = "item [@ column = 'left']">
<xsl: variable name = "vPos" select = "position ()" />
<item left = "{@ value}"
right = "{../ item [@ column = 'right'] [$ vPos] / @ value}" />
</ xsl: template>
<xsl: template match = "item [@ column = 'right']">
<item left = "" right = "{@ value}" />
</ xsl: template>
</ xsl: stylesheet>
when applied to the provided XML document:
<data>
<item column = "left" value = "1" />
<item column = "left" value = "2" />
<item column = "right" value = "3" />
<item column = "left" value = "4" />
<item column = "right" value = "5" />
<item column = "right" value = "6" />
<item column = "right" value = "7" />
<item column = "left" value = "8" />
<item column = "right" value = "9" />
<item column = "right" value = "10" />
</data>
creates the desired result:
<data>
<item left = "1" right = "3" />
<item left = "2" right = "5" />
<item left = "4" right = "6" />
<item left = "8" right = "7" />
<item left = "" right = "9" />
<item left = "" right = "10" />
</data>
You would use element and attribute tags ...
<xsl:element name="item"> <xsl:attribute name="left"><xsl:value-of select="$theLeft"/></xsl:attribute> <xsl:attribute name="right"><xsl:value-of select="$theRight"/></xsl:attribute> </xsl:element> ... as for the algorithm for determining what should be $ theLeft and $ theRight, I leave it to you.