xslt 1.0 - Grouping elements based on criteria and eliminating duplicates -
i have problem on grouping elements based on criteria , eliminating duplicates.
i have 2 records in xml. document 1 , document 2
the objective create table 3 sections. same, add, delete. elements both in record should come in same subsection quantities. element not there in doc 1 , present in doc 2 should come add subsection , elements there in doc 1 , not present in doc 2 should come delete subsection.
here able create 3 subsections total. problem identify similar elements based on rec_no in same document , sum quantities.
here output table comments.
--------------------------------------------------------- section recno desc doc-1 qty doc-2 qty total --------------------------------------------------------- same 111 desc1 1 2 300 same 444 desc4 6 4 1000 --------------------------------------------------------- same total 1300 --------------------------------------------------------- add 333 desc3 3 0 300 add 555 desc5 5 0 500 --------------------------------------------------------- add total 800 --------------------------------------------------------- delete 222 desc2 0 2 200 delete 777 desc7 0 7 700 delete 888 desc8 0 10 1000 --------------------------------------------------------- delete total 1900 --------------------------------------------------------- grand total 4000 ---------------------------------------------------------
here xml
<logia> <docheader> <document> <downto> <rec_no>111</rec_no> <desc>desc1</desc> <qty>1</qty> <value>100.00</value> </downto> <downto> <rec_no>333</rec_no> <desc>desc3</desc> <qty>3</qty> <value>300.00</value> </downto> <downto> <rec_no>444</rec_no> <desc>desc4</desc> <qty>6</qty> <value>400.00</value> </downto> <downto> <rec_no>555</rec_no> <desc>desc5</desc> <qty>5</qty> <value>500.00</value> </downto> </document> <document> <downto> <rec_no>222</rec_no> <desc>desc2</desc> <qty>2</qty> <value>200.00</value> </downto> <downto> <rec_no>111</rec_no> <desc>desc1</desc> <qty>2</qty> <value>100.00</value> </downto> <downto> <rec_no>444</rec_no> <desc>desc4</desc> <qty>4</qty> <value>400.00</value> </downto> <downto> <rec_no>777</rec_no> <desc>desc7</desc> <qty>7</qty> <value>700.00</value> </downto> <downto> <rec_no>888</rec_no> <desc>desc8</desc> <qty>8</qty> <value>800.00</value> </downto> <downto> <rec_no>888</rec_no> <desc>desc8</desc> <qty>2</qty> <value>800.00</value> </downto> </document> </docheader> </logia>
and here xslt
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="doc1" match="document[1]/downto" use="rec_no" /> <xsl:key name="doc2" match="document[2]/downto" use="rec_no" /> <xsl:template match="/logia/docheader"> <table border="1"> <!-- header --> <tr> <th>section</th> <th>recno</th> <th>desc</th> <th>doc-1 qty</th> <th>doc-2 qty</th> <th> total</th> </tr> <!-- same --> <xsl:variable name="same" select="document[1]/downto[key('doc2', rec_no )]" /> <xsl:apply-templates select="$same"> <xsl:with-param name="section">same</xsl:with-param> </xsl:apply-templates> <xsl:variable name="same-total" select="sum($same/value)" /> <tr> <td colspan="5">same total</td> <th><xsl:value-of select="$same-total"/></th> </tr> <!-- add --> <xsl:variable name="add" select="document[1]/downto[not(key('doc2', rec_no ))]" /> <xsl:apply-templates select="$add"> <xsl:with-param name="section">add</xsl:with-param> </xsl:apply-templates> <xsl:variable name="add-total" select="sum($add/value)" /> <tr> <td colspan="5">add total</td> <th><xsl:value-of select="$add-total"/></th> </tr> <!-- delete --> <xsl:variable name="delete" select="document[2]/downto[not(key('doc1', rec_no ))]" /> <xsl:apply-templates select="$delete"> <xsl:with-param name="section">delete</xsl:with-param> </xsl:apply-templates> <xsl:variable name="delete-total" select="sum($delete/value)" /> <tr> <td colspan="5">delete total</td> <th><xsl:value-of select="$delete-total"/></th> </tr> <!-- grand total --> <tr> <th colspan="5">grand total</th> <th><xsl:value-of select="$same-total + $add-total + $delete-total"/></th> </tr> </table> </xsl:template> <xsl:template match="downto"> <xsl:param name="section"/> <tr> <td><xsl:value-of select="$section"/></td> <td><xsl:value-of select="rec_no"/></td> <td><xsl:value-of select="desc"/></td> <td><xsl:value-of select="qty"/></td> <td><xsl:value-of select="qty"/></td> <td><xsl:value-of select="value"/></td> </tr> </xsl:template> </xsl:stylesheet>
any appreciated.
there not change in code:
new key:
<xsl:key name="docbyrecno" match="document/downto" use="rec_no" />
modify template matches downto:
<xsl:template match="downto"> <xsl:param name="section"/> <xsl:if test="generate-id() = generate-id(key('docbyrecno', rec_no)[1])"> <tr> <td><xsl:value-of select="$section"/></td> <td><xsl:value-of select="rec_no"/></td> <td><xsl:value-of select="desc"/></td> <td><xsl:value-of select="sum(key('doc1', rec_no)/qty)"/></td> <td><xsl:value-of select="sum(key('doc2', rec_no)/qty)"/></td> <td><xsl:value-of select="sum(key('docbyrecno', rec_no)/value)"/></td> </tr> </xsl:if> </xsl:template>
here select downto records first elements in group same rec_no (muench grouping).
Comments
Post a Comment