XSLT 按元素值分组

本文关键字:元素 XSLT | 更新日期: 2023-09-27 17:56:30

我有一个XML文件,我需要一个XSL样式表来分组它并获得输出。

<Orders>
    <Order>
        <Client>1234</Client>
        <Amendments>True</Amendments>
        <Address>
            <ID>311</ID>
            <CompanyName>Test</CompanyName>
            <StreetAddress>Sri Lanka</StreetAddress>
        </Address>
        <Line>
            <Client>1234</Client>
            <ItemCode>B100V</ItemCode>
            <Cost>$2.00</Cost>
            <Qty>2</Qty>
            <Group>g2</Group>
        </Line>
        <Line>
            <Client>1234</Client>
            <ItemCode>B102V</ItemCode>
            <Cost>$1.25</Cost>
            <Qty>4</Qty>
            <Group>g3</Group>
        </Line>
        <Line>
            <Client>1234</Client>
            <ItemCode>B140V</ItemCode>
            <Cost>$3.05</Cost>
            <Qty>1</Qty>
            <Group>g1</Group>
        </Line>
        <Line>
            <Client>1234</Client>
            <ItemCode>B113V</ItemCode>
            <Cost>$5.00</Cost>
            <Qty>5</Qty>
            <Group>g2</Group>
        </Line>
    </Order>
</Orders>

我需要按节点显示每个行组Group ItemIdCost,并且每个组都需要换行符。任何人都可以提供帮助吗?

请注意我的预期输出:

1 of B140V - $3.05  $3.05
                    ------
                    $3.05
2 of B100V - $2.00  $4.00
5 of B113V - $5.00  $25.00
                    ------
                    $29.00
4 of B102V - $1.25  $5.00
                    ------
                    $5.00

XSLT 按元素值分组

以下是快速解决方案:

示例输入(具有多个组的 XML)

<?xml version="1.0" encoding="UTF-8"?>
<Orders>
   <Order>
      <Client>1234</Client>
      <Amendments>True</Amendments>
      <Address>
         <ID>311</ID>
         <CompanyName>Test</CompanyName>
         <StreetAddress>Sri Lanka</StreetAddress>
      </Address>
      <Line>
         <Client>1234</Client>
         <ItemCode>B100V</ItemCode>
         <Cost>$2.23</Cost>
         <Qty>2</Qty>
         <Group>g2</Group>
      </Line>
      <Line>
         <Client>1234</Client>
         <ItemCode>B102V</ItemCode>
         <Cost>$1.25</Cost>
         <Qty>4</Qty>
         <Group>g3</Group>
      </Line>
      <Line>
         <Client>1234</Client>
         <ItemCode>B102V</ItemCode>
         <Cost>$10.57</Cost>
         <Qty>10</Qty>
         <Group>g3</Group>
      </Line>
      <Line>
         <Client>1234</Client>
         <ItemCode>B140V</ItemCode>
         <Cost>$3.05</Cost>
         <Qty>1</Qty>
         <Group>g1</Group>
      </Line>
      <Line>
         <Client>1234</Client>
         <ItemCode>B140V</ItemCode>
         <Cost>$7.05</Cost>
         <Qty>7</Qty>
         <Group>g1</Group>
      </Line>
      <Line>
         <Client>1234</Client>
         <ItemCode>B113V</ItemCode>
         <Cost>$5.00</Cost>
         <Qty>5</Qty>
         <Group>g2</Group>
      </Line>
      <Line>
         <Client>1234</Client>
         <ItemCode>B113V</ItemCode>
         <Cost>$9.00</Cost>
         <Qty>6</Qty>
         <Group>g2</Group>
      </Line>
   </Order>
</Orders>
XSLT 

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common">
<xsl:strip-space elements="*" /> <xsl:output method="text" />
    <xsl:key name="group" match="Line" use="Group" />
    <xsl:template match="Order">
        <AllUsers>
            <xsl:apply-templates select="Line[generate-id(.)=generate-id(key('group',Group)[1])]"/>
        </AllUsers>
    </xsl:template>
    <xsl:template match="Line">
         <Line>
            <xsl:for-each select="key('group',Group)">
 <Qty><xsl:value-of select="Qty" /></Qty> of <ItemCode><xsl:value-of select="ItemCode" /></ItemCode> - <Cost><xsl:value-of select="Cost" /></Cost>
<xsl:variable name="vTwice"> 
<xsl:call-template name="sumProducts">
        <xsl:with-param name="mul1" select="Qty"/>
<xsl:with-param name="mul2" select="substring-after(Cost,'$')"/>
      </xsl:call-template>
</xsl:variable>
  <xsl:value-of select="$vTwice"/>
<xsl:text>&#xa;</xsl:text>
</xsl:for-each><xsl:text>&#x9;</xsl:text><xsl:text>&#x9;</xsl:text><xsl:text>&#x9;</xsl:text>------
<xsl:text>&#x9;</xsl:text><xsl:text>&#x9;</xsl:text><xsl:text>&#x9;</xsl:text>
<xsl:variable name="test">
<xsl:for-each select="key('group',Group)"><mine>
<xsl:value-of select="substring-after(Cost,'$') * Qty"/></mine>
</xsl:for-each>
</xsl:variable>
 <total>
            <xsl:variable name="myTotal" select="exslt:node-set($test)"/>
            <xsl:value-of select="concat('$',format-number(sum($myTotal/mine),'#.00'))" />
        </total>
<xsl:text>&#xa;</xsl:text>
          </Line>
    </xsl:template>
<xsl:template name="sumProducts">
        <xsl:param name="mul1"/>
        <xsl:param name="mul2"/> <xsl:text>&#x9;</xsl:text>  
<result><xsl:value-of select='concat("$",format-number(($mul1 * $mul2), "#.00"))'/></result>
</xsl:template>
</xsl:stylesheet>

得到以下结果:

2 of B100V - $2.23	$4.46
5 of B113V - $5.00	$25.00
6 of B113V - $9.00	$54.00
			------
			$83.46
4 of B102V - $1.25	$5.00
10 of B102V - $10.57	$105.70
			------
			$110.70
1 of B140V - $3.05	$3.05
7 of B140V - $7.05	$49.35
			------
			$52.40