XSLT: сумма фрагмента дерева всегда будет возвращать 0! - PullRequest
1 голос
/ 17 февраля 2009

Я застрял с проблемой, которая кажется глупой, но я не могу найти решение ... С 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)"/>

Ответы [ 3 ]

0 голосов
/ 17 февраля 2009

Вот быстрый способ суммирования динамически сгенерированных значений (Возможно, вызываемый вами шаблон не дает ожидаемых результатов? Если это так, вы должны задать другой вопрос и предоставить как код, так и 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
0 голосов
/ 23 марта 2018

В моем случае у меня была точно такая же проблема, как сумма ($ что-то / элемент) вернула 0 и сумма ($ что-то / *) вернула правильное значение.

Моя проблема была вызвана следующим объявлением таблицы стилей UBL Invoice:

XMLNS = "урна: оазис: Названия: Спецификация: Ubl: схема: XSD: Счет-2"

После удаления этой строки сумма ($ что-то / элемент) вернула правильное значение.

0 голосов
/ 17 февраля 2009

Рекурсия - это обычный ответ на функциональных языках. Что-то вроде:

<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 для установки узла контекста для рекурсивного вызова.

...