Pregunta

Estoy atascado con un problema que parece estúpido, pero no puedo encontrar la solución ... Con XLST, necesito sumar una lista de los valores calculados por una plantilla. Así que almacenan estos valores en una estructura de árbol (una lista de elementos "Número" contenidos en un elemento raíz "Numbers"). Pero lo que trato de hacer con esta lista hecho a sí mismo, se devolverá o bien nada, 0 o un error ...

¿Alguien sabe lo que estoy haciendo mal?

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

Solución

Aquí está una manera rápida Cómo sumar valores generados dinámicamente (Probablemente la plantilla que llama no está produciendo los resultados esperados? Si es así, debe hacer otra pregunta y proporcionar tanto el código como el documento XML en el que opera el código sin ellos no se puede ayudar y conjeturas no sería ú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>

Cuando se aplica la transformación anterior en cualquier documento XML (ignorado), el resultado deseado se produce :

3

Otros consejos

La recursividad es la respuesta habitual en los lenguajes funcionales. Algo así 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>

Sin saber más de GetSize y el documento de entrada es difícil ser más específico sobre el XPath derecho de fijar el nodo de contexto para la llamada recursiva.

En mi caso, yo tenía exactamente el mismo problema que suma ($ algo / elemento) devuelto 0 y suma ($ algo / *) devuelve el valor correcto.

Mi problema fue causado por la siguiente declaración de estilo UBL Factura:

xmlns = "urn: oasis: names: Especificación: UBL: esquema: xsd: Factura-2"

Después de eliminar esta línea, suma ($ algo / elemento) devuelto el valor correcto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top