在Xslt

时间:2017-11-30 11:46:14

标签: xml templates xslt

有一张桌子,桌子有5排。有些行具有相同的<Name>

如果<Quantity>相同,我想在一行中显示同名的行并添加<UnitPrice>

我有xml和xslt,我看到了:

ID  Name    UnitPrice   Quantity 
1   A       5           30 
2   A       5           40 
3   A       6           50 
4   C       6           25 
5   V       10          15 

我想看看

1   A   10  70 
3   A   6   50 
4   C   6   25 
5   V   10  15 

我有那个xml:

<Items>
    <Item>
        <ID>1</ID>
        <Name>A</Name>
        <UnitPrice>5</UnitPrice>
        <Quantity>30</Quantity>
    </Item>
    <Item>
        <ID>2</ID>
        <Name>A</Name>
        <UnitPrice>5</UnitPrice>
        <Quantity>40</Quantity>
    </Item>
    <Item>
        <ID>3</ID>
        <Name>A</Name>
        <UnitPrice>6</UnitPrice>
        <Quantity>50</Quantity>
    </Item>
    <Item>
        <ID>4</ID>
        <Name>C</Name>
        <UnitPrice>6</UnitPrice>
        <Quantity>25</Quantity>
    </Item>
    <Item>
        <ID>5</ID>
        <Name>V</Name>
        <UnitPrice>10</UnitPrice>
        <Quantity>15</Quantity>
    </Item>
</Items>

我做了一个类似的xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>      
      <body>
        <table>
          <tbody>
            <tr>
              <td width ="50">ID</td>
              <td width ="50">Name</td>
              <td width ="50">UnitPrice</td>
              <td width ="50">Quantity</td>           
            </tr>        
            <xsl:for-each select = "//Items/Item" >
              <xsl:apply-templates select = "." />
            </xsl:for-each>
          </tbody>
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="//Items/Item">
    <tr>
      <td><xsl:value-of select="./ID"/></td>
      <td><xsl:value-of select="./Name"/></td>
      <td><xsl:value-of select="./UnitPrice"/></td>
      <td><xsl:value-of select="./Quantity"/></td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:2)

请尝试使用以下XSLT对相似元素进行分组,然后访问该组以获取所需的输出。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <body>
                <table>
                    <tbody>
                        <tr>
                            <td width="50">ID</td>
                            <td width="50">Name</td>
                            <td width="50">UnitPrice</td>
                            <td width="50">Quantity</td>
                        </tr>
                        <xsl:for-each-group select="//Items/Item" group-by="concat(Name,'|',UnitPrice)">
                            <tr>
                                <td><xsl:value-of select="ID" /></td>
                                <td><xsl:value-of select="Name" /></td>
                                <td><xsl:value-of select="sum(current-group()/UnitPrice)" /></td>
                                <td><xsl:value-of select="sum(current-group()/Quantity)" /></td>
                            </tr>
                        </xsl:for-each-group>
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:2)

在XSLT 1.0中,您可以使用Muenchian Grouping

您希望按NameUnitPrice进行分组,因此您需要创建一个复合键(类似于另一个答案中的group-by)。

然而,将UnitPrice加起来是没有意义的,所以我将假设10 in:

1 A 10 70

在您想要的输出中是一个错字。如果这是一个不正确的假设,UnitPrice也可以与Quantity求和的方式相似:

sum(key('items',concat(Name,'|',UnitPrice))/UnitPrice)

完整示例......

XML

<Items>
    <Item>
        <ID>1</ID>
        <Name>A</Name>
        <UnitPrice>5</UnitPrice>
        <Quantity>30</Quantity>
    </Item>
    <Item>
        <ID>2</ID>
        <Name>A</Name>
        <UnitPrice>5</UnitPrice>
        <Quantity>40</Quantity>
    </Item>
    <Item>
        <ID>3</ID>
        <Name>A</Name>
        <UnitPrice>6</UnitPrice>
        <Quantity>50</Quantity>
    </Item>
    <Item>
        <ID>4</ID>
        <Name>C</Name>
        <UnitPrice>6</UnitPrice>
        <Quantity>25</Quantity>
    </Item>
    <Item>
        <ID>5</ID>
        <Name>V</Name>
        <UnitPrice>10</UnitPrice>
        <Quantity>15</Quantity>
    </Item>
</Items>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:key name="items" match="Item" use="concat(Name, '|', UnitPrice)"/>

  <xsl:template match="/">
    <html>
      <body>
        <table>
          <tbody>
            <tr>
              <td width="50">ID</td>
              <td width="50">Name</td>
              <td width="50">UnitPrice</td>
              <td width="50">Quantity</td>
            </tr>
            <xsl:apply-templates 
            select="Items/Item[count(.|key('items',concat(Name,'|',UnitPrice))[1])=1]"/>
          </tbody>
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="Item">
    <tr>
      <td><xsl:value-of select="ID"/></td>
      <td><xsl:value-of select="Name"/></td>
      <td><xsl:value-of select="UnitPrice"/></td>
      <td>
        <xsl:value-of 
        select="sum(key('items',concat(Name,'|',UnitPrice))/Quantity)"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

输出(点击“运行代码段”查看格式化的HTML。)

<html>
   <body>
      <table>
         <tbody>
            <tr>
               <td width="50">ID</td>
               <td width="50">Name</td>
               <td width="50">UnitPrice</td>
               <td width="50">Quantity</td>
            </tr>
            <tr>
               <td>1</td>
               <td>A</td>
               <td>5</td>
               <td>70</td>
            </tr>
            <tr>
               <td>3</td>
               <td>A</td>
               <td>6</td>
               <td>50</td>
            </tr>
            <tr>
               <td>4</td>
               <td>C</td>
               <td>6</td>
               <td>25</td>
            </tr>
            <tr>
               <td>5</td>
               <td>V</td>
               <td>10</td>
               <td>15</td>
            </tr>
         </tbody>
      </table>
   </body>
</html>