Pregunta

Tengo algunos resultados de software de terceros:

XML de muestra del software:

<testsuite name="XYZ">  
    <testcase name="ABC" status="0" time="12.001">Some stuff</testcase>  
    <testcase name="DEF" status="0" time="12,345.001">Some stuff</testcase>  
    <testcase name="GHI" status="0" time="4,321.001">Some stuff</testcase>     
</testsuite>

Necesito escribir un XSLT que transforme esto en lo siguiente:

<testsuite name="XYZ" time="16678.003">
    <testcase name="ABC" time="12.001">Some stuff</testcase>
    <testcase name="DEF" time="12,345.001">Some stuff</testcase>
    <testcase name="GHI" time="4,321.001">Some stuff</testcase>    
</testsuite>

Y casi he llegado allí, con la excepción del atributo tiempo del elemento testuite . En lugar de obtener el total, obtengo NaN . La expresión XPath que estoy usando para obtener esto es sum(//testsuite/@time)

Tenga en cuenta que el error no ocurre cuando todas las veces son < 1000. Esto probablemente se deba a que XSLT no analiza el número cuando encuentra comas. (No puedo eliminar estas comas de la entrada porque proviene de software de terceros).

Entonces, ¿cómo sumo estos valores por tiempo? ¿Hay alguna forma de modificar sum (// testsuite / @ time) de modo que pueda quitar comas sobre la marcha?

¡Gracias!

¿Fue útil?

Solución

Use esta plantilla recursiva para agregar todos los atributos de tiempo juntos:

<xsl:template name="sumoftime">
  <xsl:param name="node"/>
  <xsl:param name="sum" />
  <xsl:choose>
    <xsl:when test="$node">
      <xsl:call-template name="sumoftime">
        <xsl:with-param name="node" select="$node/following-sibling::testcase[1]"/>
        <xsl:with-param name="sum" select="$sum + number(translate($node/@time, ',', ''))"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$sum"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Y luego, en su elemento de prueba, haga una llamada a la plantilla anterior

<xsl:element name="testsuite">

            ...

    <xsl:attribute name="{'time'}">
        <xsl:call-template name="sumoftime">
            <xsl:with-param name="node" select="testcase[1]"/>
            <xsl:with-param name="sum" select="0" />
        </xsl:call-template>
    </xsl:attribute>
</xsl:element>

Es bastante complicado, pero si está restringido a XSLT 1.0, creo que este sería el camino a seguir.

El crédito por la plantilla debe ir a Jelovirt, ya que es solo una ligera modificación de su respuesta a otra pregunta: stackoverflow.com/questions/647991/summing-numbers-with-comma-as-decimal-separator-in-xslt

Otros consejos

Use la translate función de esta manera: p>

  

sum(translate(//testsuite/@time,',',''))

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