2009-03-15 9 views

Antwort

6

Ich vermute, dass der in einem "val" Attribut angegebene Wert eine Zahl ist, die Komma anstelle eines Dezimalpunkts hat.

sind mehrere Lösungen möglich:

I. XSLT 1.0

Diese Transformation:

<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="foo"> 
     <xsl:variable name="vrtfBars"> 
     <xsl:for-each select="bar"> 
      <bar val="{translate(@val, ',', '.')}"/> 
     </xsl:for-each> 
     </xsl:variable> 
<!--           --> 
     <xsl:value-of select= 
     "sum(ext:node-set($vrtfBars)/*/@val)"/> 
    </xsl:template> 
</xsl:stylesheet> 

wenn auf dem ursprünglich bereitgestellten XML-Dokument angewendet:

<foo> 
    <bar val="1,23"/> 
    <bar val="4,56"/> 
    <bar val="7,89"/> 
</foo> 

erzeugt das gewünschte Ergebnis:

13.68 

II. XSLT 2,0

Diese Transformation:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
exclude-result-prefixes="f xs" 
> 
<xsl:output method="text"/> 
<!--           --> 
<xsl:template match="foo"> 
    <xsl:sequence select= 
    "sum(bar/@val/number(translate(., ',', '.')))" 
    /> 
</xsl:template> 
</xsl:stylesheet> 

, wenn auf dem gleichen XML-Dokument angewendet wird, erzeugt die gleiche korrekte Ergebnis:

13,68

III. FXSL 2.x

Diese Transformation:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:f="http://fxsl.sf.net/" 
xmlns:my="my:fun" 
exclude-result-prefixes="my f xs" 
> 
    <xsl:import href="../f/func-transform-and-sum.xsl"/> 
<!--           --> 
<xsl:output method="text"/> 
<!--           --> 
<xsl:template match="foo"> 
    <xsl:sequence select= 
    "sum(
     f:transform-and-sum(my:makeNum(), bar/@val) 
     )" 
    /> 
</xsl:template> 
<!--           --> 
<xsl:function name="my:makeNum" as="xs:double"> 
    <xsl:param name="psNum" as="xs:string"/> 
<!--           --> 
    <xsl:sequence select="number(translate($psNum, ',', '.'))"/> 
</xsl:function> 
<!--           --> 
<xsl:function name="my:makeNum" as="element()"> 
    <my:makeNum/> 
</xsl:function> 
<!--           --> 
<xsl:template match="my:makeNum" as="xs:double" mode="f:FXSL"> 
    <xsl:param name="arg1" as="xs:string"/> 
<!--           --> 
    <xsl:sequence select="my:makeNum($arg1)"/> 
</xsl:template> 
</xsl:stylesheet> 

, wenn auf dem gleichen XML-Dokument angewendet erzeugt die gleiche korrekte Ergebnis:

13,68

Die letzte Lösung ist flexibler und kann erfolgreich verwendet werden, wenn mehr com Plex Transformation der Werte ist vor der Summierung erforderlich.

+0

Vielen Dank für die sehr präzise Antwort :-) –

2

Ich fühle mich wie ich sage das viel, aber es wiederholt sich: der ganze Sinn von XML ist, dass es Daten in einer leicht zu analysierenden Form bereitstellt. XML, das Daten enthält, die nicht als XML analysiert werden können, ist nicht sinnvoll; Wenn möglich, sollten Sie entweder Ihr XML reparieren oder ein anderes Format verwenden.

+1

Aber viel der Welt verwendet ein, für Dezimaltrennzeichen. Warum ist . der Einzige zu sein, der erlaubt ist? –

+0

Robert, ich stimme dir vollkommen zu. In meinem Fall werden XML-Dateien jedoch von einer Drittanbieteranwendung erstellt, auf die ich keinen Einfluss habe. –

+1

Das einzige Dezimaltrennzeichen, das von der Funktion XSLT number() unterstützt wird, ist ".". –

3

Angenommen, das gleiche wie Dimitre, dass Sie Komma als Dezimaltrennzeichen, nicht als Trennzeichen für die Liste der ganzen Zahlen verwenden.

Reines XSLT 1.0 ohne EXSLT Knotensatzerweiterung:

<xsl:template match="foo"> 
    <xsl:call-template name="sum"> 
    <xsl:with-param name="node" select="bar[1]"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="sum"> 
    <xsl:param name="node"/> 
    <xsl:param name="sum" select="0"/> 
    <xsl:choose> 
    <xsl:when test="$node"> 
     <xsl:call-template name="sum"> 
     <xsl:with-param name="node" select="$node/following-sibling::bar[1]"/> 
     <xsl:with-param name="sum" select="$sum + translate($node/@val, ',', '.')"/> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$sum"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
Verwandte Themen