recursion - XSLT grouping recursive problem -
guys, recursion grouping not working. using xslt 1.0. need figure out. in advance.
background: have 3 different types (common, category, & complex) in xml. goal to.
1 - group xml nodes based on types. 2 - create sub-group complex under type=common. 3 - type=complex create number of collections depending upon source xml. in each collection should list 4 elements name='a' or 'b' or 'c' or 'd'. i'm having problem. grouping , sub-grouping working fine. however, when try create collection using recursion not giving me intending output. reference please see expected out xml sample.
source xml:
<?xml version="1.0" encoding="windows-1252"?> <xml> <attributes> <attribute> <name>buyer id</name> <type>common</type> <value>lee</value> </attribute> <attribute> <name>enviornment</name> <type>common</type> <value>dev</value> </attribute> <attribute> <name>retail</name> <type>common</type> <value></value> </attribute> <attribute> <name>gender</name> <type>category</type> <value>m</value> </attribute> <attribute> <name>collection</name> <type>complex</type> <value>ing</value> <path /> </attribute> <attribute> <name>a</name> <type>complex</type> <value>testing</value> <path /> </attribute> <attribute> <name>b</name> <type>complex</type> <value>yellow</value> <path /> </attribute> <attribute> <name>c</name> <type>complex</type> <value>10</value> <path /> </attribute> <attribute> <name>d</name> <type>complex</type> <value>ma</value> <path /> </attribute> <attribute> <name>a</name> <type>complex</type> <value>24a</value> <path /> </attribute> <attribute> <name>b</name> <type>complex</type> <value>green</value> <path /> </attribute> <attribute> <name>c</name> <type>complex</type> <value>22</value> <path /> </attribute> <attribute> <name>d</name> <type>complex</type> <value>am</value> <path /> </attribute> </attributes> </xml> expected output:
<?xml version="1.0" encoding="utf-8"?> <data schema="xml a"> <items> <item> <attributes type="common"> <attr name="buyer id" value="lee" /> <attr name="enviornment" value="dev" /> <attr name="retail" value="" /> <collection name="collection" > <complex> <attr name="a" value="testing" /> <attr name="b" value="yellow" /> <attr name="c" value="10" /> <attr name="d" value="ma" /> </complex> <complex> <attr name="a" value="24a" /> <attr name="b" value="green" /> <attr name="c" value="22" /> <attr name="d" value="am" /> </complex> </collection> </attributes> <attributes type="category"> <attr name="gender" value="m" /> </attributes> <errorcodes> <errorcode>value retail missing.</errorcode> </errorcodes> </item> </items> </data> here xslt
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:key name="type" match="attribute" use="type"/> <xsl:variable name="group" select="4"/> <xsl:template match="/"> <data schema="xml a"> <items> <item> <xsl:apply-templates select="xml/attributes/attribute[generate-id() = generate-id(key('type', type)[1])]"> <xsl:sort select="type" order="descending"/> </xsl:apply-templates> <errorcodes> <xsl:apply-templates select="xml/attributes/attribute" mode="errors"/> </errorcodes> </item> </items> </data> </xsl:template> <xsl:template match="attribute"> <xsl:variable name="comptype" select="count(/xml/attributes/attribute[type='complex' , name!='collection'])"/> <xsl:if test="type!='complex'"> <attributes type="{type}"> <xsl:apply-templates select="key('type',type)" mode="out"/> <xsl:if test="type='common'"> <collection> <xsl:for-each select="/xml/attributes/attribute[type='complex']"> <xsl:choose> <xsl:when test="(name='a' or name='b' or name='c' or name='d')"> <xsl:if test="(($comptype > 0) , (name!='collection'))"> <xsl:apply-templates select="key('type','complex')" mode="out"/> </xsl:if> </xsl:when> <xsl:otherwise> <complex> <attr id="" name="a" value="default" /> <attr id="" name="b" value="default" /> <attr id="" name="c" value="default" /> <attr id="" name="d" value="" /> </complex> </xsl:otherwise> </xsl:choose> </xsl:for-each> </collection> </xsl:if> </attributes> </xsl:if> </xsl:template> <xsl:template match="attribute" mode="out"> <collection> <attr name="{name}" value="{value}"/> </collection> </xsl:template> <xsl:template match="attribute[type='complex']" mode="out"> <xsl:apply-templates select="xml/attributes/attribute[not(name='collection')] [position() mod $group = 1]" mode="group"/> </xsl:template> <xsl:template match="name" mode="group"> <xsl:if test="name!='collection'"> <attr name="{name}" value="{value}"/> </xsl:if> </xsl:template> <xsl:template match="attribute"> <complex> <xsl:apply-templates select=".|following-sibling::attribute[position() < $group]" mode="inner" /> </complex> </xsl:template> <xsl:template match="attribute" mode="errors"> <xsl:if test="(name='retail' or name='product description') , value=''"> <errorcode>value <xsl:value-of select="name"/> missing.</errorcode> </xsl:if> </xsl:template> </xsl:stylesheet>
i not sure understand requirements following sample
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:data="http://example.com/data" exclude-result-prefixes="data" version="1.0"> <xsl:output indent="yes"/> <xsl:key name="att-by-type" match="attributes/attribute" use="type"/> <xsl:variable name="complex" select="key('att-by-type', 'complex')"/> <xsl:template match="xml"> <data schema="xml a"> <items> <item> <xsl:apply-templates select="attributes/attribute[type = 'common' or type = 'category'][generate-id() = generate-id(key('att-by-type', type)[1])]" mode="group"/> </item> </items> </data> </xsl:template> <xsl:template match="attribute" mode="group"> <attributes type="{type}"> <xsl:apply-templates select="key('att-by-type', type)"/> <xsl:if test="type = 'common'"> <collection name="collection"> <xsl:apply-templates select="$complex[name = 'a']" mode="comp-group"/> </collection> </xsl:if> </attributes> </xsl:template> <xsl:template match="attribute" mode="comp-group"> <complex> <xsl:variable name="pos" select="position()"/> <xsl:apply-templates select="$complex[name = 'a'][position() = $pos] | $complex[name = 'b'][position() = $pos] | $complex[name = 'c'][position() = $pos] | $complex[name = 'd'][position() = $pos]"/> </complex> </xsl:template> <xsl:template match="attribute"> <attr name="{name}" value="{value}"/> </xsl:template> </xsl:stylesheet> produces output posted (with exception of errorcodes, left out seemed unrelated other problem).
Comments
Post a Comment