仅在节点中存在特定值时求和,排除其他值



我使用XSLT 2.0仅根据以下条件对特定值求和:

  • 如果wd:Analytical_amount大于0,则使用分析值
  • 如果wd:Analytical_amount等于0,使用总发票值

下面是示例XML:

<?xml version='1.0' encoding='UTF-8'?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<wd:Report_Data
xmlns:wd="trans_file">
<wd:Report_Entry>
<wd:Transaction_Number>415077</wd:Transaction_Number>
<wd:Customer_Invoice_Lines_group>
<wd:Analytical_amount>500</wd:Analytical_amount>
</wd:Customer_Invoice_Lines_group>
<wd:Customer_Invoice_Lines_group>
<wd:Analytical_amount>0</wd:Analytical_amount>
</wd:Customer_Invoice_Lines_group>
<wd:Customer_Invoice_Lines_group>
<wd:Analytical_amount>1000</wd:Analytical_amount>
</wd:Customer_Invoice_Lines_group>
<wd:Total_Invoice_amount>5000</wd:Total_Invoice_amount>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Transaction_Number>494700</wd:Transaction_Number>
<wd:Customer_Invoice_Lines_group>
<wd:Analytical_amount>0</wd:Analytical_amount>
</wd:Customer_Invoice_Lines_group>
<wd:Total_Invoice_amount>2000</wd:Total_Invoice_amount>
</wd:Report_Entry>
<!--Edit: added more XML nodes -->
<wd:Report_Entry>
<wd:Transaction_Number>494111</wd:Transaction_Number>
<wd:Customer_Invoice_Lines_group>
<wd:Analytical_amount>0</wd:Analytical_amount>
</wd:Customer_Invoice_Lines_group>
<wd:Total_Invoice_amount>1000</wd:Total_Invoice_amount>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Transaction_Number>494222</wd:Transaction_Number>
<wd:Customer_Invoice_Lines_group>
<wd:Analytical_amount>500</wd:Analytical_amount>
</wd:Customer_Invoice_Lines_group>
<wd:Total_Invoice_amount>4000</wd:Total_Invoice_amount>
</wd:Report_Entry>
</wd:Report_Data>
</env:Body>
</env:Envelope>

XSLT使用:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:wd="trans_file"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="text" encoding="UTF-8" indent="yes"/> 
<xsl:variable name="linefeed" select="'&#xd;&#xa;'"/>
<xsl:variable name="delimiter" select="'|'"/>        
<xsl:template match="wd:Report_Data">
<xsl:value-of select="count(wd:Report_Entry/wd:Transaction_Number)"/>
<xsl:value-of select="$delimiter"/>
<xsl:value-of select="format-number(sum(//wd:Customer_Invoice_Lines_group/wd:Analytical_amount[. != '0']),'#.00')"/> 
<xsl:value-of select="$delimiter"/>    
<xsl:if test="wd:Report_Entry/wd:Customer_Invoice_Lines_group/*[not(wd:Analytical_amount != 0)]">
<xsl:value-of select="format-number(sum(wd:Report_Entry/wd:Total_Invoice_amount),'#.##')"/>

<xsl:value-of select="$delimiter"/>
<xsl:value-of select="$linefeed"/>
<xsl:value-of select="$delimiter"/>
</xsl:template>
</xsl:stylesheet>

结果我得到:2 | 1500.00 | 7000.0 |

期望的基于文本的输出:2 | 1500.00 | 2000.0 |

编辑XML后的新结果:4 | 2000.00 | 6000.0 |

XSLT-1.0的解决方案是

<xsl:template match="wd:Report_Data">
<xsl:value-of select="count(wd:Report_Entry/wd:Transaction_Number)"/>
<xsl:value-of select="$delimiter"/>
<xsl:for-each select="wd:Report_Entry">
<xsl:choose>
<xsl:when test="sum(wd:Customer_Invoice_Lines_group/wd:Analytical_amount) > 0">
<xsl:value-of select="format-number(sum(wd:Customer_Invoice_Lines_group/wd:Analytical_amount),'#.00')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="format-number(wd:Total_Invoice_amount,'#.00')"/>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="$delimiter"/>
</xsl:for-each>
<xsl:value-of select="$linefeed"/>
</xsl:template>

和一个更简单的XSLT-2.0解决方案

<xsl:template match="wd:Report_Data">
<xsl:value-of select="count(wd:Report_Entry/wd:Transaction_Number)"/>
<xsl:value-of select="$delimiter"/>
<xsl:for-each select="wd:Report_Entry">
<xsl:value-of select="if (sum(wd:Customer_Invoice_Lines_group/wd:Analytical_amount) > 0) then format-number(sum(wd:Customer_Invoice_Lines_group/wd:Analytical_amount),'#.00') else format-number(wd:Total_Invoice_amount,'#.00')"/>
<xsl:value-of select="$delimiter"/>
</xsl:for-each>
<xsl:value-of select="$linefeed"/>
</xsl:template>

最新更新