2

我想要一个如下表组织的结果:

**Costc 1000**          
    Product code    Quantity    Total amount

    SALESCOST       1   120.04
    LEASINGRENT     1   59.90

**Costc 2000**          
    Product code    Quantity    Total amount

    SALESCOST       1   118.94
    LEASINGCOST     1   513.34

**Costc 3000**          
    Product code    Quantity    Total amount

    LEASINGCOST     1   658.24
    LEASINGRENT     2   100.80

我的输入文件看起来像这样。

<?xml version="1.0" encoding="iso-8859-1"?>
<Details>
    <Detail>
        <LineNo>1</LineNo>
    <Products>
        <ProductCode>SALESCOST</ProductCode>
        <ProductDescr>Sales amount asset:997000000000</ProductDescr>
        <Quantity>1.00</Quantity>
    </Products>
    <Costc>
        <Value>2000</Value>
    </Costc>
    <TotAmount>118.94</TotAmount>
</Detail>
<Detail>
    <LineNo>2</LineNo>
    <Products>
        <ProductCode>LEASINGCOST</ProductCode>
        <ProductDescr>Leasing cost asset:997000000003</ProductDescr>
    </Products>
    <Costc>
        <Value>2000</Value>
    </Costc>
    <Quantity>1.00</Quantity>
    <TotAmount>513.34</TotAmount>
</Detail>
<Detail>
    <LineNo>3</LineNo>
    <Products>
        <ProductCode>SALESCOST</ProductCode>
        <ProductDescr>Sales amount asset:997000000001</ProductDescr>
    </Products>
    <Costc>
        <Value>1000</Value>
    </Costc>
    <Quantity>1.00</Quantity>
    <TotAmount>120.04</TotAmount>
</Detail>
<Detail>
    <LineNo>4</LineNo>
    <Products>
        <ProductCode>LEASINGCOST</ProductCode>
        <ProductDescr>Leasing cost asset:997000000002</ProductDescr>
    </Products>
    <Costc>
        <Value>3000</Value>
    </Costc>
    <Quantity>1.00</Quantity>
    <TotAmount>658.24</TotAmount>
</Detail>
<Detail>
    <LineNo>5</LineNo>
    <Products>
        <ProductCode>LEASINGRENT</ProductCode>
        <ProductDescr>Leasing interest asset:997000000001</ProductDescr>
    </Products>
    <Costc>
        <Value>3000</Value>
    </Costc>
    <Quantity>1.00</Quantity>
    <TotAmount>48.90</TotAmount>
</Detail>
<Detail>
    <LineNo>6</LineNo>
    <Products>
        <ProductCode>LEASINGRENT</ProductCode>
        <ProductDescr>Leasing interest asset:997000000002</ProductDescr>
    </Products>
    <Costc>
        <Value>3000</Value>
    </Costc>
    <Quantity>1.00</Quantity>
    <TotAmount>51.90</TotAmount>
</Detail>
<Detail>
    <LineNo>7</LineNo>
    <Products>
        <ProductCode>LEASINGRENT</ProductCode>
        <ProductDescr>Leasing interest asset:997000000002</ProductDescr>
    </Products>
    <Costc>
        <Value>1000</Value>
    </Costc>
    <Quantity>1.00</Quantity>
    <TotAmount>59.90</TotAmount>
</Detail>

如何才能做到这一点?它的多级分组以及求和和计数功能,对我来说太复杂了。非常感谢

4

2 回答 2

2

在 XSLT 1.0 中,您需要使用一种称为 Meunchian Grouping 的技术。在这种情况下,您首先按Costc元素分组,然后按Products元素分组。

这意味着您需要定义两个键。首先按Costc对详细信息进行分组

<xsl:key name="costc" match="Detail" use="Costc/Value"/>

然后按CostcProduct对详细信息进行分组

<xsl:key name="product" match="Detail" use="concat(Costc/Value, '|', Products/ProductCode)"/>

(请注意在连接中使用竖线字符。重要的是此字符不会出现在值或产品代码中)。

然后,要按 Costc元素进行分组,您可以执行以下操作:

<xsl:apply-templates 
   select="Detail[generate-id() = generate-id(key('costc', Costc/Value)[1])]">

这将为您提供每个独特Costc元素的第一个Detail元素。然后,对于每个这样的组,您将按该组中的产品进行分组。

<xsl:apply-templates 
   select="../Detail
      [Costc/Value = current()/Costc/Value]
      [generate-id() 
         = generate-id(key('product', concat(Costc/Value, '|', Products/ProductCode))[1])]"  />

因此,给定以下 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes"/>

   <xsl:key name="costc" match="Detail" use="Costc/Value"/>
   <xsl:key name="product" match="Detail" use="concat(Costc/Value, '|', Products/ProductCode)"/>

   <xsl:template match="/Details">
      <xsl:apply-templates select="Detail[generate-id() = generate-id(key('costc', Costc/Value)[1])]" mode="Cost">
         <xsl:sort select="Costc/Value" />
      </xsl:apply-templates>
   </xsl:template>

   <xsl:template match="Detail" mode="Cost">
      <h1><xsl:value-of select="Costc/Value" /></h1>
      <table>
         <tr>
            <td>Product Code</td>
            <td>Quantity</td>
            <td>Total amount</td>
         </tr>
         <xsl:apply-templates select="../Detail[Costc/Value = current()/Costc/Value][generate-id() = generate-id(key('product', concat(Costc/Value, '|', Products/ProductCode))[1])]" mode="Product" />
      </table>
   </xsl:template>

   <xsl:template match="Detail" mode="Product">
         <tr>
            <td><xsl:value-of select="Products/ProductCode" /></td>
            <td><xsl:value-of select="sum(key('product', concat(Costc/Value, '|', Products/ProductCode))//Quantity)" /></td>
            <td><xsl:value-of select="sum(key('product', concat(Costc/Value, '|', Products/ProductCode))/TotAmount)" /></td>
         </tr>
   </xsl:template>
</xsl:stylesheet>

当应用于您的示例 XML 时,将输出以下内容:

<h1>1000</h1>
<table>
    <tr>
        <td>Product Code</td>
        <td>Quantity</td>
        <td>Total amount</td>
    </tr>
    <tr>
        <td>SALESCOST</td>
        <td>1</td>
        <td>120.04</td>
    </tr>
    <tr>
        <td>LEASINGRENT</td>
        <td>1</td>
        <td>59.9</td>
    </tr>
</table>
<h1>2000</h1>
<table>
    <tr>
        <td>Product Code</td>
        <td>Quantity</td>
        <td>Total amount</td>
    </tr>
    <tr>
        <td>SALESCOST</td>
        <td>1</td>
        <td>118.94</td>
    </tr>
    <tr>
        <td>LEASINGCOST</td>
        <td>1</td>
        <td>513.34</td>
    </tr>
</table>
<h1>3000</h1>
<table>
    <tr>
        <td>Product Code</td>
        <td>Quantity</td>
        <td>Total amount</td>
    </tr>
    <tr>
        <td>LEASINGCOST</td>
        <td>1</td>
        <td>658.24</td>
    </tr>
    <tr>
        <td>LEASINGRENT</td>
        <td>2</td>
        <td>100.8</td>
    </tr>
</table>
于 2012-02-09T23:23:27.547 回答
1

这个怎么样?

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <xsl:output method="text"/>

    <xsl:template match="/">
        <xsl:for-each-group select="*/Detail" group-by="Costc/Value" >
            <xsl:sort select="current-grouping-key()" order="ascending"/>

            <xsl:value-of select="concat('** Costc ',current-grouping-key())"/>
            <xsl:text>&#xD;&#xA;  Product code    Quantity    Total amount&#xD;&#xA;</xsl:text>

            <xsl:for-each-group select="current-group()" group-by="Products/ProductCode" >
                <xsl:text>   </xsl:text>            
                <xsl:value-of select="current-grouping-key()"/>
                <xsl:text>   </xsl:text>
                <xsl:value-of select="number(sum(current-group()/Quantity, current-group()/Products/Quantity))" />              
                <xsl:text>   </xsl:text>
                                <xsl:value-of select="sum(current-group()/TotAmount)" />                
                <xsl:text>&#xD;&#xA;</xsl:text>             
            </xsl:for-each-group>       

            <xsl:text>&#xD;&#xA;</xsl:text>

        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

您将不得不调整格式。此 XSLT 仅提供算法。这是我的输出:

** Costc 1000
  Product code    Quantity    Total amount
   SALESCOST   1   120.04
   LEASINGRENT   1   59.9

** Costc 2000
  Product code    Quantity    Total amount
   SALESCOST   1   118.94
   LEASINGCOST   1   513.34

** Costc 3000
  Product code    Quantity    Total amount
   LEASINGCOST   1   658.24
   LEASINGRENT   2   100.8
于 2012-02-09T21:56:46.827 回答