在XSLT for-each-group中选择不同的值

时间:2013-05-06 01:05:41

标签: xml xslt xpath

我在为每个组选择不同的值时遇到问题。结果不会显示在屏幕上。所需的结果如下所示:

<xsl:for-each-group select="Items/Item" group-by="ProviderName">
    <xsl:sort select="current-grouping-key()"/>
    <tr>
        <th>
            <xsl:value-of select="current-grouping-key()"/>
        </th>
    </tr>
    <tr>
        <td>
            <xsl:text>Item Number</xsl:text>
        </td>
        <td>
            <xsl:text>Quantity</xsl:text>
        </td>
        <td>
            <xsl:text>Unit Price</xsl:text>
        </td>
        <td>
            <xsl:text>Total</xsl:text>
        </td>
    </tr>
    <xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>

我打算在current-group()标记中为apply-templates选择不同的

    <xsl:template match="Item">
        <xsl:value-of select="distinct-values(./ItemName)"/>
    </xsl:template>

我在网上阅读了几个样本,最佳方法是使用带有generate-id()循环的for-each-group函数。但我试过并没有得到积极的结果。这是源XML:

<Items>
    <Item ItemNumber="1148087">
        <ProductName>Dolby Metal-Black-Matte</ProductName>
        <ProviderName>Vestal Watches</ProviderName>
        <Quantity>4</Quantity>
        <UnitPrice>67.99</UnitPrice>
    </Item>
    <Item ItemNumber="1150197">
        <ProductName>Vercilli Blk-Tan</ProductName>
        <ProviderName>Boston Babes</ProviderName>
        <Quantity>1</Quantity>
        <UnitPrice>23.99</UnitPrice>
    </Item>
    <Item ItemNumber="1151464">
        <ProductName>Spritz Grape Seat and Extra Seat</ProductName>
        <ProviderName>Bambeano</ProviderName>
        <Quantity>1</Quantity>
        <UnitPrice>56.99</UnitPrice>
    </Item>
    <Item ItemNumber="1148087">
        <ProductName>Dolby Metal-Black-Matte</ProductName>
        <ProviderName>Vestal Watches</ProviderName>
        <Quantity>2</Quantity>
        <UnitPrice>67.99</UnitPrice>
    </Item>
    <Item ItemNumber="1150197">
        <ProductName>Vercilli Blk-Tan</ProductName>
        <ProviderName>Boston Babes</ProviderName>
        <Quantity>2</Quantity>
        <UnitPrice>23.99</UnitPrice>
    </Item>
    <Item ItemNumber="1150173">
        <ProductName>Lucille Tan</ProductName>
        <ProviderName>Boston Babes</ProviderName>
        <Quantity>1</Quantity>
        <UnitPrice>24.99</UnitPrice>
    </Item>
    <Item ItemNumber="1151464">
        <ProductName>Spritz Grape Seat and Extra Seat</ProductName>
        <ProviderName>Bambeano</ProviderName>
        <Quantity>1</Quantity>
        <UnitPrice>56.99</UnitPrice>
    </Item>
    <Item ItemNumber="1148089">
        <ProductName>Plexi Leather-Silver-Black</ProductName>
        <ProviderName>Vestal Watches</ProviderName>
        <Quantity>1</Quantity>
        <UnitPrice>189.99</UnitPrice>
    </Item>
</Items>

请注意,源XML包含几个具有不同ProductName属性的ItemNumber元素。我想要的是将所有Item个元素与ItemNumber相似,并对数量求和。谢谢你的帮助。真的很感激。

示例输出将是:  enter image description here

2 个答案:

答案 0 :(得分:3)

请查看修改后的XSLT版本:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="yes"/>

  <xsl:template match="/">
    <table>
      <thead>
        <tr>
          <th>
            <xsl:text>Item Number</xsl:text>
          </th>
          <th>
            <xsl:text>Quantity</xsl:text>
          </th>
          <th>
            <xsl:text>Unit Price</xsl:text>
          </th>
          <th>
            <xsl:text>Total</xsl:text>
          </th>
        </tr>
      </thead>
      <tbody>
        <xsl:for-each-group select="Items/Item" group-by="@ItemNumber">
          <xsl:sort select="current-grouping-key()"/>
          <tr>
            <td>
              <xsl:value-of select="current-grouping-key()"/>
            </td>
            <td>
              <xsl:value-of select="sum(current-group()/Quantity)"/>
            </td>
            <td>
              <xsl:value-of select="current-group()/UnitPrice"/>
            </td>
            <td>
              <xsl:value-of
                select="sum(for $x in current-group() return $x/UnitPrice * $x/Quantity)"/>
            </td>
          </tr>
          <xsl:apply-templates select="current-group()"/>
        </xsl:for-each-group>
      </tbody>
    </table>
  </xsl:template>

  <xsl:template match="Item">
    <xsl:value-of select="distinct-values(./ItemName)"/>
  </xsl:template>
</xsl:stylesheet>

输出:

<table>
   <thead>
      <tr>
         <th>Item Number</th>
         <th>Quantity</th>
         <th>Unit Price</th>
         <th>Total</th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>1148087</td>
         <td>6</td>
         <td>67.99</td>
         <td>407.93999999999994</td>
      </tr>
      <tr>
         <td>1148089</td>
         <td>1</td>
         <td>189.99</td>
         <td>189.99</td>
      </tr>
      <tr>
         <td>1150173</td>
         <td>1</td>
         <td>24.99</td>
         <td>24.99</td>
      </tr>
      <tr>
         <td>1150197</td>
         <td>3</td>
         <td>23.99</td>
         <td>71.97</td>
      </tr>
      <tr>
         <td>1151464</td>
         <td>2</td>
         <td>56.99</td>
         <td>113.98</td>
      </tr>
   </tbody>
</table>

答案 1 :(得分:0)

我认为你只想嵌套两个for-each-group

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

<xsl:output method="html" version="5.0" indent="yes"/>

<xsl:template match="Items">
  <table>
    <xsl:for-each-group select="Item" group-by="ProviderName">
      <tbody>
        <tr>
          <th colspan="4">Provider: <xsl:value-of select="current-grouping-key()"/></th>
        </tr>
        <tr>
          <th>Item Number</th>
          <th>Quantity</th>
          <th>Unit Price</th>
          <th>Total</th>
        </tr>
      </tbody>
      <tbody>
        <xsl:for-each-group select="current-group()" group-by="@ItemNumber">
          <tr>
            <td><xsl:value-of select="current-grouping-key()"/></td>
            <td><xsl:value-of select="sum(current-group()/Quantity)"/></td>
            <td><xsl:value-of select="UnitPrice"/></td>
            <td><xsl:value-of select="format-number(sum(current-group()/(Quantity * UnitPrice)), '0.00')"/></td>
          </tr>
        </xsl:for-each-group>
      </tbody>
      <tbody>
        <tr>
          <th colspan="3">Subtotal</th>
          <td><xsl:value-of select="format-number(sum(current-group()/(Quantity * UnitPrice)), '0.00')"/></td>
        </tr>
      </tbody>
    </xsl:for-each-group>
      <tbody>
        <tr>
          <th colspan="3">Total</th>
          <td><xsl:value-of select="format-number(sum(Item/(Quantity * UnitPrice)), '0.00')"/></td>
        </tr>
      </tbody>
  </table>
</xsl:template>

</xsl:stylesheet>