xslt - How to group at more than one level? -
i have xml file:
<document> <line id="0"> <field id="2">x111</field> <field id="3">1</field> <field id="4">222222222222</field> </line> <line id="1"> <field id="2">x111</field> <field id="3">1</field> <field id="4">111111111111</field> </line> <line id="2"> <field id="2">x222</field> <field id="3">1</field> <field id="4">111111111111</field> </line> <line id="3"> <field id="2">x222</field> <field id="3">1></field> <field id="4">111111111111</field> </line> <line id="4"> <field id="2">x333</field> <field id="3">1</field> <field id="4">111111111111</field> </line> </document> from xml file should group field2 (after field4 ), question not how group field 2 , 3 documents how group field4 if same?
output:
<document> <result> <header> <field2>x111</field2> </header> <line> <position>1</position> <field4>222222222222</field4> <sum>1<sum> <position>2</position> <field4>111111111111</field4> <sum>1<sum> </line> </result> <result> <header> <field2>x222</field2> </header> <line> <position>1</position> <field4>111111111111</field4> <sum>2<sum> </line> </result> <result> <header> <field2>x333</field2> </header> <line> <position>1</position> <field4>111111111111</field4> <sum>1</sum> </line> </result> </document> i'm stuck in grouping lines, didn't know how group same , different fields id= 4.
my program looks:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:fo="http://www.w3.org/1999/xsl/format"> <xsl:output method="xml" encoding="utf-8" indent="yes"/> <xsl:key name="kline" match="line" use="string(field[@id=2])"/> <xsl:key name="bline" match="line" use="field[@id=4]"/> <xsl:template match="document"> <document> <xsl:apply-templates select="line[count( . | key('kline', string(field[@id='2']))[1]) = 1]"/> </document> </xsl:template> <xsl:template match="line"> <xsl:variable name="field2" select="field[@id='2']"/> <result> <header> <xsl:value-of select="field[@id='2']"/> </header> <line> <xsl:for-each select="//line[field[@id='2']=$field2]"> <position> <xsl:value-of select="position()"/> </position> <field4><xsl:value-of select="field[@id='4']"/></field4> <sum><xsl:value-of select="sum(key('bline', field[@id='4'])/field[@id='3'])"/></sum> </xsl:for-each> </line> </result> </xsl:template> </xsl:stylesheet>
you're asking how group @ multiple levels. following stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:key name="byfield2" match="line" use="field[@id='2']" /> <xsl:key name="byfield2andfield4" match="line" use="concat(field[@id='2'], '|', field[@id='4'])" /> <xsl:template match="/"> <document><xsl:apply-templates /></document> </xsl:template> <xsl:template match="line[generate-id() = generate-id(key('byfield2', field[@id='2'])[1])]"> <result> <header> <field2><xsl:value-of select="field[@id='2']" /></field2> </header> <line> <xsl:apply-templates select="key('byfield2', field[@id='2']) [generate-id() = generate-id(key('byfield2andfield4', concat(field[@id='2'], '|', field[@id='4']))[1])]" mode="field4" /> </line> </result> </xsl:template> <xsl:template match="line" mode="field4"> <position><xsl:value-of select="position()" /></position> <field4><xsl:value-of select="field[@id='4']" /></field4> <sum> <xsl:value-of select="sum(key('byfield2andfield4', concat(field[@id='2'], '|', field[@id='4']))/ field[@id='3'])" /> </sum> </xsl:template> <xsl:template match="line" /> </xsl:stylesheet> on input:
<document> <line id="0"> <field id="2">x111</field> <field id="3">1</field> <field id="4">222222222222</field> </line> <line id="1"> <field id="2">x111</field> <field id="3">1</field> <field id="4">111111111111</field> </line> <line id="2"> <field id="2">x222</field> <field id="3">1</field> <field id="4">111111111111</field> </line> <line id="3"> <field id="2">x222</field> <field id="3">1></field> <field id="4">111111111111</field> </line> <line id="4"> <field id="2">x333</field> <field id="3">1</field> <field id="4">111111111111</field> </line> </document> produces desired result:
<document> <result> <header> <field2>x111</field2> </header> <line> <position>1</position> <field4>222222222222</field4> <sum>1</sum> <position>2</position> <field4>111111111111</field4> <sum>1</sum> </line> </result> <result> <header> <field2>x222</field2> </header> <line> <position>1</position> <field4>111111111111</field4> <sum>2</sum> </line> </result> <result> <header> <field2>x333</field2> </header> <line> <position>1</position> <field4>111111111111</field4> <sum>1</sum> </line> </result> </document> we use 2 keys. first groups field 2. second groups concatenation of fields 2 , 4.
Comments
Post a Comment