组合多个键

时间:2014-12-04 09:08:54

标签: xslt

我在组合多个密钥以获取更改记录时遇到问题。

我有2条XML记录。文件1和文件2

目标是创建一个包含4个部分的表。相同,更改,添加和删除。

两个文档中具有相同rec_no,part_no,ext_qty的元素应该在相同的子节中。 Document1中没有Document2中的元素需要在Delete子部分下 Document2中没有Document2中的元素需要在Add子部分下 上述3个条件中不存在的元素应在变更小节内。例如,有一个记录 这两个文件以及数量或部件号或描述都有任何变化

现在我可以毫无问题地添加前3个部分,问题出现在第4个条件中。我无法结合前三个 得到这些条件的条件。

这是带有我的评论的输出表。这里的记录999在删除部分,不应该在更改子部分

----------------------------------------------------
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 
----------------------------------------------------

这是我的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>

我的XSL如下

<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>

1 个答案:

答案 0 :(得分:1)

<xsl:variable name="change" select="Document[1]/Downto[
    key('MAT2PARTKEY', part_no) and not(
        key('MATERIAL2BYKEY', concat(rec_no, '||',  part_no, '||', ext_qty))
    )
]" />