Converting an Input XML to OTHER XML using XSLT [closed]

shbakawy

New Member
Possible Duplicate:
Converting input xml using xslt to other XML I am astarter in XSLT. I have looked some codes for the task i was interested on and built some logic but i could not get into the desired output. I am glad if i could get a help.Input XML:<?xml version="1.0" encoding="UTF-8"?><t><Data> <CD> <Artist>xxx.yyy</Artist> <song>abc</song> </CD> <CD> <Artist>xxx.zzz</Artist> <song>cba</song> </CD> <CD> <Artist>aaa.kkk</Artist> <song>123</song> </CD> <CD> <Artist>aaa.lll</Artist> <song>456</song> </CD> <CD> <Artist>ddd</Artist> <song>1234</song> </CD></Data><Music> <music_no>E123</music_no> <music_type>outdoor</music_type> <Artist>bat.ball</Artist> <value>0000</value></Music><Music> <music_no>E123</music_no> <music_type>outdoor</music_type> <Artist>bat.stone</Artist> <value>0001</value></Music><Music> <music_no>E111</music_no> <music_type>outdoor</music_type> <Artist>board.coins</Artist> <value>0002</value></Music><Music> <music_no>E111</music_no> <music_type>outdoor</music_type> <Artist>board.ball</Artist> <value>0003</value></Music><Music> <music_no>E001</music_no> <music_type>indoor</music_type> <Artist>bat.ball</Artist> <value>8888</value></Music><Music> <music_no>E001</music_no> <music_type>indoor</music_type> <Artist>bat.stone</Artist> <value>9999</value></Music><Music> <music_no>E111</music_no> <music_type>indoor</music_type> <Artist>board.coins</Artist> <value>0001</value></Music><Music> <music_no>E111</music_no> <music_type>indoor</music_type> <Artist>bat</Artist> <value>0001</value></Music></t>Expected Output:<?xml version="1.0" encoding="UTF-8"?><version_3><information> <xxx> <yyy>abc</yyy> <zzz>cba</zzz> </xxx> <aaa> <kkk>123</kkk> <lll>456</lll> </aaa> <ddd>1234</ddd></information><information> <bat> <ball>0000</ball> <stone>0001</stone> </bat> <board> <coins>0002</coins> <ball>0003</ball> </board> <bat> <ball>8888</ball> <stone>9999</stone> </bat> <board> <coins>0001</coins> </board></information><information> <bat>0001</bat></information> </version_3>Edited Expected Output:Expected Output:<?xml version="1.0" encoding="UTF-8"?><version_3><information> <xxx> <yyy>abc</yyy> <zzz>cba</zzz> </xxx> <aaa> <kkk>123</kkk> <lll>456</lll> </aaa> <ddd>1234</ddd></information><information> <bat> <ball>0000</ball> <stone>0001</stone> </bat></information><information> <board> <coins>0002</coins> <ball>0003</ball> </board> <board> <coins>0001</coins> <bat>0001</bat> </board></information><information> <bat> <ball>8888</ball> <stone>9999</stone> </bat> </information> </version_3>In the above Input XML: you can notice "CD" element and values in it, similarly "music". I want to get an output that looks like,Sample output for "CD": <information> <xxx> <yyy>abc</yyy> <zzz>cba</zzz> </xxx> <aaa> <kkk>123</kkk> <lll>456</lll> </aaa> <ddd>1234</ddd></information>I could Achieve this to some extent by Muenchian Grouping. But, The next Element "Music" has sub elements in which, the first two elements "music_no" & "music_type" get matched then the Values in the "Artist" has to be grouped. If they arent matched they have to be seperately grouped.Sample o/p for Music:<information> <bat> <ball>0000</ball> <stone>0001</stone> </bat> <board> <coins>0002</coins> <ball>0003</ball> </board> <bat> <ball>8888</ball> <stone>9999</stone> </bat> <board> <coins>0001</coins> </board></information><information> <bat>0001</bat></information>I could not achieve the second part as it is bit tricky with iterations. Help is Appreciated.Note: for the "Music" element if the Value in the Artist resembles the same with the corresponding nodes but having no "." then that Value has to be seperately grouped that is outside "information" and shall have new "information"My Code that i Worked on: <?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext"><xsl:key name="kBychildName" match="CD" use="name(Artist/*[1])"/><xsl:key name="kByAttribs" match="Artist" use="concat(../@music_no, '+', ../@music_type)"/><xsl:key name="kChildByAttribsAndArtist" match="Artist/*" use="concat(../../@music_no, '+', ../../@music_type, '+', name())"/><xsl:template match="/"> <version_3> <information> <xsl:variable name="var1"> <xsl:apply-templates/> </xsl:variable> <xsl:apply-templates mode="pass2" select="ext:node-set($var1)/* [generate-id()=generate-id(key('kBychildName',name(Artist/*[1]))[1]) or not(Artist/*)]"/> </information> <information> <xsl:variable name="var2"> <xsl:apply-templates/> </xsl:variable> <xsl:apply-templates mode="pass3" select="ext:node-set($var2)/*/* [generate-id() = generate-id(key('kByAttribs', concat(../@music_no, '+', ../@music_type) ) [1])] "/> </information> </version_3> <!--xsl:copy-of select="//msg_debug"/--></xsl:template><xsl:template match="CD[contains(Artist,'.')]"> <CD> <Artist> <xsl:element name="{substring-before(Artist, '.')}"> <xsl:element name="{substring-after(Artist, '.')}"> <xsl:value-of select="song"/> </xsl:element> </xsl:element> </Artist> </CD></xsl:template><xsl:template match="CD"> <CD> <Artist> <xsl:element name="{Artist}"> <xsl:value-of select="song"/> </xsl:element> </Artist> </CD></xsl:template><xsl:template match="CD" mode="pass2"><xsl:apply-templates select="*/*[1]" mode="pass2"/></xsl:template><xsl:template match="Artist/*" mode="pass2"> <xsl:copy> <xsl:copy-of select="self::*[not(*)]/text()|key('kBychildName', name())/*/*/*"/> </xsl:copy></xsl:template><xsl:template match="Music[contains(Artist, '.')]"> <Music music_no="{music_no}" music_type="{music_type}"> <Artist> <xsl:element name="{substring-before(Artist, '.')}"> <xsl:element name="{substring-after(Artist, '.')}"> <xsl:value-of select="value"/> </xsl:element> </xsl:element> </Artist> </Music></xsl:template><xsl:template match="Music"> <Music music_no="{music_no}" music_type="{music_type}"> <Artist> <xsl:element name="{Artist}"> <xsl:value-of select="value"/> </xsl:element> </Artist> </Music></xsl:template><xsl:template match="Artist" mode="pass3"> <!--Artist--> <xsl:apply-templates mode="pass3" select="*[generate-id() =generate-id(key('kChildByAttribsAndArtist', concat(../../@music_no, '+', ../../@music_type,'+', name()))[1] ) ]"/> <xsl:copy-of select="key('kByAttribs',concat(../@music_no, '+', ../@music_type) )/*[not(*)] "/> <!--/Artist--></xsl:template><xsl:template match="Artist/*" mode="pass3"> <xsl:element name="{name()}"> <xsl:copy-of select="key('kChildByAttribsAndArtist', concat(../../@music_no, '+', ../../@music_type, '+', name()) )/* "/> </xsl:element></xsl:template> </xsl:stylesheet>I am glad to explain the problem again, if found difficult. As a beginners to XSLT i hope you can help me.
 
Back
Top