XSLT transformation from flat structure to nested -
i cannot manage simple (?) xslt transformation.
there input flat-structured xml:
<root> <attribute_a>abc</attribute_a> <attribute_b>def</attribute_b> <attribute_c>ghi</attribute_c> <attribute_a>123</attribute_a> <attribute_b>456</attribute_b> <attribute_c>789</attribute_c> <attribute_a>xxx</attribute_a> <attribute_b>xxx</attribute_b> <attribute_c>xxx</attribute_c> </root>
i should transform xml this:
<root> <attribute> <attribute_a>abc</attribute_a> <attribute_b>def</attribute_b> <attribute_c>ghi</attribute_c> </attribute> <attribute> <attribute_a>123</attribute_a> <attribute_b>456</attribute_b> <attribute_c>789</attribute_c> </attribute> <attribute> <attribute_a>xxx</attribute_a> <attribute_b>xxx</attribute_b> <attribute_c>xxx</attribute_c> </attribute> </root>
but problem after transformation that:
<?xml version="1.0" encoding="utf-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" indent="yes" /> <xsl:template match="/"> <root> <xsl:for-each select="root/attribute_a"> <attribute> <attribute_a> <xsl:value-of select="../attribute_a" /> </attribute_a> <attribute_b> <xsl:value-of select="../attribute_b" /> </attribute_b> <attribute_c> <xsl:value-of select="../attribute_c" /> </attribute_c> </attribute> </xsl:for-each> </root> <xsl:apply-templates /> </xsl:template> </xsl:stylesheet>
i got this:
<?xml version="1.0" encoding="utf-8"?> <root> <attribute> <attribute_a>abc</attribute_a> <attribute_b>def</attribute_b> <attribute_c>ghi</attribute_c> </attribute> <attribute> <attribute_a>abc</attribute_a> <attribute_b>def</attribute_b> <attribute_c>ghi</attribute_c> </attribute> <attribute> <attribute_a>abc</attribute_a> <attribute_b>def</attribute_b> <attribute_c>ghi</attribute_c> </attribute> </root>
i not experienced in xslt - have ideas? :(
regards, a. m.
this should trick:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()" /> </xsl:copy> </xsl:template> <xsl:template match="/"> <root> <xsl:for-each select="root/attribute_a"> <xsl:variable name="pos" select="position()"/> <attribute> <xsl:apply-templates select="../attribute_a[$pos] | ../attribute_b[$pos] | ../attribute_c[$pos]" /> </attribute> </xsl:for-each> </root> </xsl:template> </xsl:stylesheet>
and i'd suggest taking 1 step farther , using separate template instead of for-each
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()" /> </xsl:copy> </xsl:template> <xsl:template match="/"> <root> <xsl:apply-templates select="root/attribute_a" mode="group" /> </root> </xsl:template> <xsl:template match="attribute_a" mode="group"> <xsl:variable name="pos" select="position()"/> <attribute> <xsl:apply-templates select="../attribute_a[$pos] | ../attribute_b[$pos] | ../attribute_c[$pos]" /> </attribute> </xsl:template> </xsl:stylesheet>
when either of these xslts run on sample input, produces output:
<root> <attribute> <attribute_a>abc</attribute_a> <attribute_b>def</attribute_b> <attribute_c>ghi</attribute_c> </attribute> <attribute> <attribute_a>123</attribute_a> <attribute_b>456</attribute_b> <attribute_c>789</attribute_c> </attribute> <attribute> <attribute_a>xxx</attribute_a> <attribute_b>xxx</attribute_b> <attribute_c>xxx</attribute_c> </attribute> </root>
xslt
No comments:
Post a Comment