Saravanan
Saravanan

Reputation: 49

Combine multiple keys

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

Answers (1)

Markus Jarderot
Markus Jarderot

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

Related Questions