xslt - ¿Cómo sumar diferentes campos en XSL cuando algunos pueden ser nulos?
null xsl-fo (3)
Tengo el siguiente XSL:
<xsl:value-of select=''translate(format-number(
Gaz/Baf/CH4
+ Gaz/Std/CH4
+ Gaz/Bsa/CH4
+ Gaz/Bbs/CH4
+ Gaz/Bhf/CH4
+ Gaz/Bin/CH4
, "### ### ### ##0.######"),".",",")'' />
La suma se suma muy bien cuando todos mis artículos tienen valores. Sin embargo, si uno de ellos es nulo ( <CH4 xsi:nil="true"/>
), mis sumas se convierten en NaN
.
Hasta ahora intenté agregar una nueva función. Pero no es compatible con el generador de pdf que usamos. ( System.Xml.Xsl.XslLoadException: ''xsl: function'' aún no está implementado )
Intenté agregar una función C # para agregarla como XsltArgumentList . Un simple return value ?? 0;
return value ?? 0;
Pero también recibo una excepción: _System.Xml.Xsl.XslTransformException: los parámetros o valores de una función de extensión con un tipo Clr ''Nullable`1'' no se gestionan _
Y ahora estoy tratando de usar una xsl:variable
pero no encuentro ningún ejemplo en el que agreguen valor a la variable (¿está definida una variable estática una vez?)
Entonces, ¿alguna sugerencia?
Encontré una solución de trabajo usando C #
Mi primer intento fue:
public decimal AddNaN(decimal? val)
{
return val ?? 0;
}
pero no le gustó el decimal?
Así que probé algo más:
public decimal AddNaN(string val)
{
decimal num = 0;
decimal.TryParse(val, out num);
return num;
}
Lo cual funcionó.
Les digo a mis alumnos que utilicen un predicado para filtrar aquellos miembros que no son números.
Entonces, en XSLT 1 usaría lo siguiente, confiando en el principio de que NaN!=NaN
:
<xsl:value-of select=''translate(format-number(
sum( ( Gaz/Baf/CH4
| Gaz/Std/CH4
| Gaz/Bsa/CH4
| Gaz/Bbs/CH4
| Gaz/Bhf/CH4
| Gaz/Bin/CH4 )[number(.)=number(.)] )
, "### ### ### ##0.######"),".",",")'' />
En XSLT 2 sería más elegante como:
<xsl:value-of select=''translate(format-number(
sum( (Gaz/Baf/CH4
| Gaz/Std/CH4
| Gaz/Bsa/CH4
| Gaz/Bbs/CH4
| Gaz/Bhf/CH4
| Gaz/Bin/CH4 )[. castable as xs:double] )
, "### ### ### ##0.######"),".",",")'' />
(Reparado por observaciones de LarsH, gracias Lars).
Puede usar la sum
de un conjunto de nodos. Me gusta esto
<xsl:value-of select="translate(format-number(
sum(Gaz/Baf/CH4|Gaz/Std/CH4|Gaz/Bsa/CH4|Gaz/Bbs/CH4|Gaz/Bhf/CH4|Gaz/Bin/CH4),
''### ### ### ##0.######''), ''.'', '','')" />
Actualizar
Tal vez podrías intentar
<xsl:variable name="ch4" select="Gaz/Baf/CH4|Gaz/Std/CH4|Gaz/Bsa/CH4|Gaz/Bbs/CH4|Gaz/Bhf/CH4|Gaz/Bin/CH4"/>
Entonces la variable $ch4
contendrá un conjunto de nodos que coincidan con esa expresión. Puedes ver cuántos nodos hay en él usando
<xsl:value-of select="count($ch4)"/>
y deberías ser capaz de calcular la suma usando
<xsl:value-of select="sum($ch4)"/>