XSLT:сумма фрагмента дерева всегда будет возвращать 0 !
Вопрос
Я застрял с проблемой, которая кажется глупой, но я не могу найти решение...С помощью XLST мне нужно суммировать список значений, вычисленных с помощью шаблона.Поэтому я сохранил эти значения в древовидной структуре (список элементов "Number", содержащихся в корневом элементе "Numbers").Но что бы я ни пытался сделать с этим самодельным списком, он вернет либо ничего, либо 0, либо ошибку...
Кто - нибудь знает , что я делаю не так ?
<!-- create the tree fragment -->
<xsl:variable name="_subTotals">
<Numbers>
<xsl:for-each select="List">
<xsl:variable name="_Size">
<xsl:call-template name="GetSize">
<xsl:with-param name="_value" select="@value"/>
</xsl:call-template>
</xsl:variable>
<Number>
<xsl:value-of select="$_Size"/>
</Number>
</xsl:for-each>
</Numbers>
</xsl:variable>
<!-- this returns an error: expression must result into a node-set -->
<xsl:message terminate="no">
<xsl:value-of select="sum($_subTotals/Numbers/Number)"/>
</xsl:message>
<!-- transform the tree fragment into a node-set
<xsl:variable name="_Total" select="msxsl:node-set($_subTotals)"/>
<!-- returns nothing -->
<xsl:for-each select="$_Total/Numbers/Number">
<xsl:message terminate="no">
<xsl:value-of select="@value"/>
</xsl:message>
</xsl:for-each>
<!-- returns 0 -->
<xsl:value-of select="sum($_Total/Numbers/Number)"/>
Решение
Вот быстрый способ суммирования динамически генерируемых значений (Вероятно, шаблон, который вы вызываете, не дает ожидаемых результатов?Если это так, вы должны задать другой вопрос и предоставить как код, так и XML-документ, с которым работает код.Без этого никто не сможет помочь, и догадки не были бы полезны.):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="vrtfNums">
<nums>
<num>1</num>
<num>2</num>
</nums>
</xsl:variable>
<xsl:variable name="vNums" select="ext:node-set($vrtfNums)"/>
<xsl:value-of select="sum($vNums/*/*)"/>
</xsl:template>
</xsl:stylesheet>
Когда вышеупомянутое преобразование применяется к любому XML-документу (игнорируется), получается желаемый результат:
3
Другие советы
Рекурсия - это обычный ответ в функциональных языках.Что - то вроде:
<xsl:template name='totalRest>
<xsl:variable nane='sub'>
<!-- Use for-each to set local new context node -->
<xsl:for-each select='following::List[1]'>
<xsl:call-template name='totalRest'/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name='this'>
<xsl:call-template name="GetSize">
<xsl:with-param name="_value" select="@value"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select='$sub+$this' />
</xsl:template>
Не зная больше о getSize и входном документе, трудно быть более конкретным в отношении правильного XPath для установки контекстного узла для рекурсивного вызова.
В моем случае у меня была точно такая же проблема, которая сумма (что-то вдолларах / элемент) вернул 0 и сумма (что-то вдолларах/*) вернул правильное значение.
Моя проблема была вызвана следующим объявлением таблицы стилей счета UBL:
xmlns="urn:oasis:имена: спецификация: ubl: схема: xsd:Счет-фактура-2"
После удаления этой строки, сумма (что-то вдолларах / элемент) вернул правильное значение.