删除重复项,同时忽略空白值并在 XSLT 中添加 LineAmount

Remove duplicates while ignoring blank values and adding LineAmount in XSLT

我有一个要求,我需要删除重复的 SGSRollupItemName,同时忽略空白的 SGSRollupItemName 并添加重复的 SGSRollupItemName 的 LineAmount。我已经编写了删除重复的 SGSRollupItemName 的代码,虽然它正在删除重复的 SGSRollupItemName,但它也删除了不重复且具有空白值的 SGSRollupItemName。 下面是输入 xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <Invoice>
        <InvoiceLines>
            <LineAmount>200.00</LineAmount>
            <SGSRollupItemName>Test</SGSRollupItemName>
            <SGSRollupItemNotes>PT</SGSRollupItemNotes>
        </InvoiceLines>
        <InvoiceLines>
            <LineAmount>300.00</LineAmount>
            <SGSRollupItemName>Test1</SGSRollupItemName>
            <SGSRollupItemNotes>PT</SGSRollupItemNotes>
        </InvoiceLines>
        <InvoiceLines>
            <LineAmount>250.00</LineAmount>
            <SGSRollupItemName>Test</SGSRollupItemName>
            <SGSRollupItemNotes>PT</SGSRollupItemNotes>
        </InvoiceLines>
        <InvoiceLines>
            <LineAmount>400.00</LineAmount>
            <SGSRollupItemName></SGSRollupItemName>
            <SGSRollupItemNotes></SGSRollupItemNotes>
        </InvoiceLines>
        <InvoiceLines>
            <LineAmount>500.00</LineAmount>
            <SGSRollupItemName></SGSRollupItemName>
            <SGSRollupItemNotes></SGSRollupItemNotes>
        </InvoiceLines>
    </Invoice>
</root>
   

这是我正在使用的 xslt 代码

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl"
                xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
  <xsl:key name="dups" match="InvoiceLines[normalize-space(SGSRollupItemName)]" use="concat(generate-id(..), '|', SGSRollupItemName)" />

  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@* | node()">
    <cXML>
      <Header/>
      <Request xslt="XML">
        <InvoiceDetailRequest>
          <InvoiceDetailRequestHeader>
          </InvoiceDetailRequestHeader>
          <xsl:for-each select="Invoice/InvoiceLines[normalize-space(SGSRollupItemName)][not(generate-id() = generate-id(key('dups',concat(generate-id(..), '|', SGSRollupItemName))[1]))]">
            <InvoiceDetailOrder>
              <InvoiceDetailItem >
                <xsl:variable name="numbers">
                  <xsl:for-each select="key('dups', concat(generate-id(..), '|',SGSRollupItemName ))/LineAmount">
                    <num>
                      <xsl:value-of select="translate(., ',', '')"/>
                    </num>
                  </xsl:for-each>
                </xsl:variable>
                <UnitPrice>
                  <Money>
                    <xsl:value-of select="format-number(sum(exsl:node-set($numbers)/num),'0.00,#')"/>
                  </Money>
                </UnitPrice>
                <NetAmount>
                  <Money>
                    <xsl:value-of select="format-number(sum(exsl:node-set($numbers)/num),'0.00,#')"/>
                  </Money>
                </NetAmount>
                <Comments>
                  <xsl:value-of select="./SGSRollupItemName/text()"/>
                </Comments>
                <Comments>
                  <xsl:value-of select ="./SGSRollupItemNotes/text()"/>
                </Comments>
              </InvoiceDetailItem>
            </InvoiceDetailOrder>
          </xsl:for-each>
        </InvoiceDetailRequest>
      </Request>
    </cXML>
  </xsl:template>
</xsl:stylesheet>

下面是我得到的输出

<?xml version="1.0" encoding="utf-8"?>
<cXML>
    <Header />
    <Request xslt="XML">
        <InvoiceDetailRequest>
            <InvoiceDetailRequestHeader />
            <InvoiceDetailOrder>
                <InvoiceDetailItem>
                    <UnitPrice>
                        <Money>450.00</Money>
                    </UnitPrice>
                    <NetAmount>
                        <Money>450.00</Money>
                    </NetAmount>
                    <Comments>Test</Comments>
                    <Comments>PT</Comments>
                </InvoiceDetailItem>
            </InvoiceDetailOrder>
        </InvoiceDetailRequest>
    </Request>
</cXML>

但下面是预期的输出

<?xml version="1.0" encoding="utf-8"?>
<cXML>
    <Header />
    <Request xslt="XML">
        <InvoiceDetailRequest>
            <InvoiceDetailRequestHeader />
            <InvoiceDetailOrder>
                <InvoiceDetailItem>
                    <UnitPrice>
                        <Money>450.00</Money>
                    </UnitPrice>
                    <NetAmount>
                        <Money>450.00</Money>
                    </NetAmount>
                    <Comments>Test</Comments>
                    <Comments>PT</Comments>
                </InvoiceDetailItem>
            </InvoiceDetailOrder>
            <InvoiceDetailOrder>
                <InvoiceDetailItem>
                    <UnitPrice>
                        <Money>300.00</Money>
                    </UnitPrice>
                    <NetAmount>
                        <Money>300.00</Money>
                    </NetAmount>
                    <Comments>Test1</Comments>
                    <Comments>PT</Comments>
                </InvoiceDetailItem>
            </InvoiceDetailOrder>
            <InvoiceDetailOrder>
                <InvoiceDetailItem>
                    <UnitPrice>
                        <Money>400.00</Money>
                    </UnitPrice>
                    <NetAmount>
                        <Money>400.00</Money>
                    </NetAmount>
                    <Comments></Comments>
                    <Comments></Comments>
                </InvoiceDetailItem>
            </InvoiceDetailOrder>
            <InvoiceDetailOrder>
                <InvoiceDetailItem>
                    <UnitPrice>
                        <Money>500.00</Money>
                    </UnitPrice>
                    <NetAmount>
                        <Money>500.00</Money>
                    </NetAmount>
                    <Comments></Comments>
                    <Comments></Comments>
                </InvoiceDetailItem>
            </InvoiceDetailOrder>
        </InvoiceDetailRequest>
    </Request>
</cXML>

能否请您指出我在 xslt 代码中做错了什么

问题不是很清楚。查看预期的输出,您似乎想要对 SGSRollupItemName 不为空的行进行分组,并分别列出空白的行。

如果是这样,请考虑以下简化示例:

XSLT 1.0

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

<xsl:key name="dups" match="InvoiceLines" use="concat(generate-id(..), '|', SGSRollupItemName)"/>

<xsl:template match="/root">
    <cXML>
        <!-- group non-blank items -->
        <xsl:for-each select="Invoice/InvoiceLines[normalize-space(SGSRollupItemName)][generate-id() = generate-id(key('dups', concat(generate-id(..), '|', SGSRollupItemName))[1])]">
            <InvoiceDetailOrder>
                <Money>
                    <xsl:value-of select="format-number(sum(key('dups', concat(generate-id(..), '|',SGSRollupItemName ))/LineAmount),'0.00')"/>
                </Money>
                <Comments>
                    <xsl:value-of select="SGSRollupItemName"/>
                </Comments>
            </InvoiceDetailOrder>
        </xsl:for-each> 
        <!-- list blank items -->
        <xsl:for-each select="Invoice/InvoiceLines[not(normalize-space(SGSRollupItemName))]">
            <InvoiceDetailOrder>
                <Money>
                    <xsl:value-of select="LineAmount"/>
                </Money>
                <Comments>
                    <xsl:value-of select="SGSRollupItemName"/>
                </Comments>
            </InvoiceDetailOrder>
        </xsl:for-each> 
    </cXML>
</xsl:template>
  
</xsl:stylesheet>

应用于您的输入示例,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<cXML>
  <InvoiceDetailOrder>
    <Money>450.00</Money>
    <Comments>Test</Comments>
  </InvoiceDetailOrder>
  <InvoiceDetailOrder>
    <Money>300.00</Money>
    <Comments>Test1</Comments>
  </InvoiceDetailOrder>
  <InvoiceDetailOrder>
    <Money>400.00</Money>
    <Comments/>
  </InvoiceDetailOrder>
  <InvoiceDetailOrder>
    <Money>500.00</Money>
    <Comments/>
  </InvoiceDetailOrder>
</cXML>