根据标准对元素进行分组并消除重复

时间:2014-11-27 06:01:36

标签: xslt-1.0

我在根据条件对元素进行分组并消除重复项时遇到问题。

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

目标是创建一个包含3个部分的表。相同,添加,删除。记录中的元素应与其数量一起出现在相同的子部分中。 Doc 1中没有出现在Doc 2中的元素应该进入Add子部分,Doc 1中没有出现在Doc 2中的元素应该进入Delete子部分。

在这里,我可以创建3个子部分。现在我的问题是在同一文档中根据rec_no识别相似的元素并将它们的数量相加。

这是带有我评论的输出表。

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

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

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

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

您的代码中没有太多变化:

新密钥:

<xsl:key name="docByRecNo" match="Document/Downto" use="rec_no" />

修改与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>

在这里,我们只选择那些具有相同rec_no(Muench分组)的组中第一个元素的Downto记录。