Reputation: 49
I have a problem on combining multiple keys for getting changed record.
I have 2 records in XML. Document 1 and Document 2
The objective is to create a table with 4 sections. Same, Change, Add and Delete.
Elements which have same rec_no, part_no, ext_qty which are there in both documents should come in the subsection Same. Elements which is there in Document1 and not in Document2 needs to be under Delete subsection Elements which is there in Document2 and not in Document1 needs to be under Add subsection Elements which are not there in above 3 conditions should be under change subsection. For Example, a record which is there in both documents and there are any changes in qty or part number or description
Now i am able to add the first 3 sections without any problem, the problem comes in the 4th condition. I am not able to combine the first 3 conditions to get a NOT of those conditions.
Here is the output table with my comments. Here the record 999 is there in Delete section and it should not come under change subsection
----------------------------------------------------
Section PartNo RecNo Desc Doc-1 Qty Doc-2 Qty Total
----------------------------------------------------
Same 111 aaa Desc1 1 1 200
----------------------------------------------------
Same Total 100
----------------------------------------------------
Change 222 bbb Desc2 2 3 200
Change 333 ccc Desc3 3 3 200
Change 444 ddd Desc4 6 4 500
Change 999 ggg Desc9 2 0 100
----------------------------------------------------
Change Total 400
----------------------------------------------------
Add 666 ff Desc4 0 6 400
----------------------------------------------------
Add Total 0
----------------------------------------------------
Delete 999 ggg Desc9 2 0 100
----------------------------------------------------
Delete Total 0
----------------------------------------------------
Grand Total 500
----------------------------------------------------
Here is my XML
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="sample.xslt"?>
<Logia>
<DocHeader>
<Document>
<Downto>
<part_no>111</part_no>
<rec_no>aaa</rec_no>
<desc>Desc1</desc>
<ext_qty>1</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>222</part_no>
<rec_no>bbb</rec_no>
<desc>Desc2</desc>
<ext_qty>2</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>333</part_no>
<rec_no>ccc</rec_no>
<desc>Desc3</desc>
<ext_qty>3</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>444</part_no>
<rec_no>ddd</rec_no>
<desc>Desc4</desc>
<ext_qty>6</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>999</part_no>
<rec_no>ggg</rec_no>
<desc>Desc9</desc>
<ext_qty>2</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
</Document>
<Document>
<Downto>
<part_no>111</part_no>
<rec_no>aaa</rec_no>
<desc>Desc1</desc>
<ext_qty>1</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>222</part_no>
<rec_no>bbb</rec_no>
<desc>Desc3</desc>
<ext_qty>3</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>333</part_no>
<rec_no>bbb</rec_no>
<desc>Desc3</desc>
<ext_qty>3</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>444</part_no>
<rec_no>ddd</rec_no>
<desc>Desc4</desc>
<ext_qty>4</ext_qty>
<mat_cost>400.00</mat_cost>
</Downto>
<Downto>
<part_no>666</part_no>
<rec_no>ff</rec_no>
<desc>Desc4</desc>
<ext_qty>6</ext_qty>
<mat_cost>400.00</mat_cost>
</Downto>
</Document>
</DocHeader>
</Logia>
and my XSL is as follows
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="MAT1PARTKEY" match="Document[1]/Downto" use="part_no" />
<xsl:key name="MAT2PARTKEY" match="Document[2]/Downto" use="part_no" />
<xsl:key name="MATERIALBYPARTNO" match="Document/Downto" use="part_no" />
<xsl:key name="MATERIAL2BYKEY" match="Document[2]/Downto" use="concat(rec_no, '||', part_no, '||', ext_qty)" />
<xsl:key name="MATERIALKEY" match="Document[1]/Downto" use="concat(rec_no, '||', part_no, '||', ext_qty)" />
<xsl:template match="/Logia/DocHeader">
<table border="1">
<!-- header -->
<tr>
<th>Section</th>
<th>PartNo</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('MATERIAL2BYKEY', concat(rec_no, '||', part_no, '||', ext_qty))]" />
<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/mat_cost)" />
<tr>
<td colspan="6">Same Total</td>
<th><xsl:value-of select="$same-total"/></th>
</tr>
<!-- change -->
<xsl:variable name="change" select="Document[1]/Downto[not(key('MATERIAL2BYKEY', concat(rec_no, '||', part_no, '||', ext_qty)))]" />
<xsl:apply-templates select="$change">
<xsl:with-param name="section">Change</xsl:with-param>
</xsl:apply-templates>
<xsl:variable name="change-total" select="sum($change/mat_cost)" />
<tr>
<td colspan="6">Change Total</td>
<th><xsl:value-of select="$change-total"/></th>
</tr>
<!-- Add -->
<xsl:variable name="add" select="Document[2]/Downto[not(key('MAT1PARTKEY', part_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="6">Add Total</td>
<th><xsl:value-of select="$add-total"/></th>
</tr>
<!-- delete -->
<xsl:variable name="delete" select="Document[1]/Downto[not(key('MAT2PARTKEY', part_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="6">Delete Total</td>
<th><xsl:value-of select="$delete-total"/></th>
</tr>
<!-- grand total -->
<tr>
<th colspan="6">Grand Total</th>
<th><xsl:value-of select="$same-total + $change-total"/></th>
</tr>
</table>
</xsl:template>
<xsl:template match="Downto">
<xsl:param name="section"/>
<xsl:if test="generate-id() = generate-id(key('MATERIALBYPARTNO', part_no)[1])">
<tr>
<td><xsl:value-of select="$section"/></td>
<td><xsl:value-of select="part_no"/></td>
<td><xsl:value-of select="rec_no"/></td>
<td><xsl:value-of select="desc"/></td>
<td><xsl:value-of select="sum(key('MAT1PARTKEY', part_no)/ext_qty)"/></td>
<td><xsl:value-of select="sum(key('MAT2PARTKEY', part_no)/ext_qty)"/></td>
<td><xsl:value-of select="sum(key('MATERIALBYPARTNO', part_no)/mat_cost)"/></td>
</tr>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 98
Reputation: 89231
<xsl:variable name="change" select="Document[1]/Downto[
key('MAT2PARTKEY', part_no) and not(
key('MATERIAL2BYKEY', concat(rec_no, '||', part_no, '||', ext_qty))
)
]" />
Upvotes: 1