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

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -