Pergunta

Eu estou preso com um problema que parece estúpido, mas eu não posso encontrar a solução ... Com XLST, eu preciso somar uma lista de valores calculados por um modelo. Então eu armazenados esses valores em uma estrutura de árvore (uma lista de elementos "número" contido em um elemento de raiz "Numbers"). Mas o que eu tento fazer com essa lista de self-made, ele retornará quer nada, 0 ou um erro ...

Alguém sabe o que estou fazendo de errado?

<!-- 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)"/>
Foi útil?

Solução

Aqui está uma maneira rápida como somar valores geradas dinamicamente (Provavelmente o modelo que você está chamando não está a produzir os resultados esperados? Se assim for, você deve fazer outra pergunta e fornecer tanto o código e o documento XML no qual o código opera sem estes ninguém pode ajudar e suposições não seria útil):..

<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>

Quando a transformação acima é aplicado em qualquer documento XML (ignorado), o resultado queria é produzido :

3

Outras dicas

A recursão é a resposta usual em linguagens funcionais. Algo como:

<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>

Sem saber mais de GetSize e do documento de entrada é difícil ser mais específico sobre o XPath para a direita para definir o nó de contexto para a chamada recursiva.

No meu caso eu tinha exatamente o mesmo problema que sum ($ algo / elemento) retornou 0 e sum ($ algo / *) devolveu o valor correto.

O meu problema foi causado pela seguinte declaração de estilo UBL Fatura:

xmlns = "urn: oásis: nomes: especificação: UBL: esquema: XSD: Fatura-2"

Depois de retirar esta linha, sum ($ algo / elemento) devolveu o valor correto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top