我一直在寻找其他解决方案,并尝试了各种方法,但仍然没有用...
这是XML结构......
<?xml version="1.0" encoding="UTF-8"?>
<query>
<continueToken/>
<results total="15">
<result recordId="16672888">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount><![CDATA[$4,000.00]]></LI_Amount>
<LI_Amount_display><![CDATA[$4,000.00]]></LI_Amount_display>
</column>
</columns>
</result>
<result recordId="16672889">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount><![CDATA[$3,000.00]]></LI_Amount>
<LI_Amount_display><![CDATA[$3,000.00]]></LI_Amount_display>
</column>
</columns>
</result>
<result recordId="16672890">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount><![CDATA[$2,000.00]]></LI_Amount>
<LI_Amount_display><![CDATA[$2,000.00]]></LI_Amount_display>
</column>
</columns>
</result>
</results>
</query>
到目前为止,这是XSL。这只是一个较大的脚本的一小部分,因此您将看到与当前问题相关的其他内容。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:datetime="http://exslt.org/dates-and-times"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="datetime">
<xsl:output method="text" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<xsl:call-template name="fixTheWidth" >
<!-- This parameter is a Id for each group of records based on the result/@recordId attribute. This groups all records to the record ID-->
<xsl:with-param name="resultIndex" select="//results/result[generate-id(.) = generate-id(key('recordID', @recordId)[1])]" />
</xsl:call-template>
</xsl:template>
<!--************************************************************************
TEMPLATE: fixTheWidth
PURPOSE: Where all the magic happens
*************************************************************************-->
<xsl:template name="fixTheWidth" match="/results">
<xsl:param name="resultIndex" /> <!-- A unique index based on grouping the records on the recordID -->
<!-- more code here, uses $resultIndex -->
<!-- Field Name: TOTAL INVOICE AMOUNT, Length = 9 (49-57), Format: numeric -->
<xsl:variable name="amount">
<xsl:call-template name="total">
<xsl:with-param name="sum" select="number(0)" />
<xsl:with-param name="startLine" select="//LI_Amount_display" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$amount" />
</xsl:template><!-- END of 'fixTheWidth' template -->
<!--****************************************************************************
TEMPLATE: total
PURPOSE: Add the total amount of all line items being processed.
*****************************************************************************-->
<xsl:template name="total" >
<xsl:param name="startLine"/>
<xsl:param name="sum"/>
<xsl:param name="newSum" select="$sum + number(translate(substring-after($startLine, '$'), ',', ''))"></xsl:param>
<!-- TEST STUB -->
<xsl:variable name="amount" select="number(translate(substring-after($startLine, '$'), ',', ''))" />
<xsl:value-of select="number(translate(substring-after($startLine, '$'), ',', ''))" />
<xsl:text> | </xsl:text>
<xsl:value-of select="$newSum + $amount" />
<xsl:text> </xsl:text>
<xsl:for-each select="$startLine/ancestor::results/following-sibling::result/columns/column/LI_Amount_display">
<!-- STUB -->
<xsl:text> for each </xsl:text>
<xsl:value-of select="number(translate(substring-after(., '$'), ',', ''))" />
<!-- Recursively Sum -->
<xsl:choose>
<xsl:when test="position() = last()">
<xsl:value-of select="$newSum"/>
</xsl:when>
<xsl:when test="$startLine/ancestor::results/following-sibling::result/columns/column/LI_Amount_display">
<xsl:call-template name="total" >
<xsl:with-param name="startLine" select="." />
<xsl:with-param name="sum" select="$newSum" />
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
最终结果
9000.00
换句话说,对所有<LI_Amount_display/>
节点求和,以便将其输出到固定宽度的平面文件中。
具体问题在于{&#34;总共&#34;中的for-each
循环中的XPath。模板。我还没有能够看到我在那个循环中,因此,select
在某种程度上是错误的...但是,这是怎么回事,为什么我&# 39;在这里。
最后,它必须是XSL 1.0版。
如果您想进一步澄清,请与我们联系。
答案 0 :(得分:5)
我不确定我理解你的要求。为什么在最终结果只是总数量的情况下编写如此复杂的样式表?此外,您似乎已经熟悉相关的EXSLT函数以及将字符串转换为数字。
<强>样式表强>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:exsl="http://exslt.org/common">
<xsl:output method="text" encoding="UTF-8" indent="no"/>
<xsl:variable name="amounts">
<xsl:for-each select="//LI_Amount_display">
<amount>
<xsl:value-of select="number(substring(translate(.,',',''),2))"/>
</amount>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<xsl:value-of select="sum(exsl:node-set($amounts)/amount)"/>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
9000
答案 1 :(得分:1)
虽然我倾向于接受MathiasMüller提出的建议,但我想展示如何使用递归命名模板来实现这一点:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<xsl:call-template name="sum-nodes" >
<xsl:with-param name="nodes" select="query/results/result/columns/column/LI_Amount_display" />
</xsl:call-template>
</xsl:template>
<xsl:template name="sum-nodes" >
<xsl:param name="nodes"/>
<xsl:param name="sum" select="0"/>
<xsl:param name="newSum" select="$sum + translate($nodes[1], '$,', '')"/>
<xsl:choose>
<xsl:when test="count($nodes) > 1">
<!-- recursive call -->
<xsl:call-template name="sum-nodes" >
<xsl:with-param name="nodes" select="$nodes[position() > 1]" />
<xsl:with-param name="sum" select="$newSum" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="format-number($newSum, '#,##0.00')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<强>结果强>:
9,000.00