Avatar billede ladyhawke Novice
18. januar 2010 - 14:23 Der er 7 kommentarer og
1 løsning

Sum af danske tal i XSLT

Jeg har noget XML fra en DataView Web Part i SharePoint.

Ideen er at jeg gerne vil summere tallene i en af kolonnerne fra denne (Distance i dette tilfælde). Da SharePointen i dette tilfælde er dansk, så er tallene f.eks.

4,5
-3,3
4
<tom værdi>
-2,1

Jeg kan godt finde frem til disse tal via XPath:
/dsQueryResponse/Rows/Row/@Distance

Men hvordan får jeg summeret tallene i XSLT, for den kan ikke håndtere det danske decimaltegn, men kun det engelske ('.').

Medtager lige stylesheet definitionen her, hvis det har betydning for mulige forslag:

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
    xmlns:d="http://schemas.microsoft.com/sharepoint/dsp"
    version="1.0" exclude-result-prefixes="xsl msxsl ddwrt"
    xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
    xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
    xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"   
    xmlns:SharePoint="Microsoft.SharePoint.WebControls"
    xmlns:ddwrt2="urn:frontpage:internal">
Avatar billede arne_v Ekspert
18. januar 2010 - 18:24 #1
kan du summere over feltet med alle komma replaced med punktum ?
Avatar billede ladyhawke Novice
18. januar 2010 - 18:32 #2
Det bør jeg kunne, men det skal jo stadig behandles som tal (mener at det er XSLT version 1) og resultatet skal vises med komma som decimal seperator, selvom udregningen er med punktum.
Avatar billede arne_v Ekspert
19. januar 2010 - 02:39 #3
Nu har jeg eksperimenteret lidt. Og det var lidt mere tricky end som så.

Men lidt googling fandt den rette inspiration.


<?xml-stylesheet type="text/xsl" href="C:/tal.xsl"?>
<alletal>
  <t>12</t>
  <t>56</t>
  <tal>12,34</tal>
  <tal>56,78</tal>
</alletal>



<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">
sum /t = <xsl:value-of select="sum(//t)"/>
sum //tal = <xsl:value-of select="sum(//tal)"/>
xsum //tal = <xsl:call-template name="xsum"><xsl:with-param name="currnode" select="//tal[1]"/></xsl:call-template>
</xsl:template>

<xsl:template name="xsum">
    <xsl:param name="currnode"/>
    <xsl:param name="res" select="0"/>
    <xsl:choose>
        <xsl:when test="$currnode">
            <xsl:call-template name="xsum">
                <xsl:with-param name="currnode" select="$currnode/following-sibling::tal[1]"/>
                <xsl:with-param name="res" select="$res + translate($currnode,',','.')"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="translate($res,'.',',')"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>



sum /t = 68
sum //tal = NaN
xsum //tal = 69,12
Avatar billede ladyhawke Novice
19. januar 2010 - 07:43 #4
sejt! Det prøver jeg lige...
Avatar billede ladyhawke Novice
19. januar 2010 - 08:03 #5
Jeg har lige prøvet på disse data:

<Rows>
  <row Distance="2,00000000000000" vægtforskel="-2,0000000000"  />
  <row Distance="3,50000000000000" Vægtforskel="1,00000000000"  />
  <row Distance="4,00000000000000" Vægtforskel="-2,0000000000"  />
  <row Distance="0" Vægtforskel="-1,50000000000"  />
</Rows>

Men jeg får ikke summen, kun værdien af 1. node (hhv. 2 og -2)

Jeg kalder den sådan her:
xsum //Distance = <xsl:call-template name="xsum"><xsl:with-param name="currnode" select="//row/@Distance[1]"/></xsl:call-template>
        xsum //Vægtforskel = <xsl:call-template name="xsum"><xsl:with-param name="currnode" select="//row/@Vægtforskel[1]"/></xsl:call-template>

Har du nogen ide om hvor jeg har bøffet i det?
Avatar billede ladyhawke Novice
19. januar 2010 - 08:15 #6
Desuden, hvordan får jeg den til at ignorere tomme felter? Altså noget a la:

<Rows>
  <row Distance="2,00000000000000" vægtforskel="-2,0000000000"  />
  <row Distance="3,50000000000000" Vægtforskel="1,00000000000"  />
  <row Distance="4,00000000000000" Vægtforskel=""  />
  <row Distance="" Vægtforskel="-1,50000000000"  />
</Rows>
Avatar billede ladyhawke Novice
20. januar 2010 - 10:28 #7
<xsl:decimal-format name="da-DK" decimal-separator="," grouping-separator="." minus-sign="-" NaN="Ikke tal"/>

  <xsl:output method="html"/>     
    <xsl:template match="/">
        <xsl:text>Distance tilbagelagt = </xsl:text>       
        <xsl:call-template name="xsum">
            <xsl:with-param name="currnode" select="//Row[1]"/>
            <xsl:with-param name="attr-type" select="'Distance'"/>
            <xsl:with-param name="res" select="0"/>
        </xsl:call-template> km


    <xsl:template name="xsum">
        <xsl:param name="currnode"/>
        <xsl:param name="attr-type"/>
        <xsl:param name="res" select="0"/>
        <xsl:choose>
            <xsl:when test="$currnode/following-sibling::Row">
                <xsl:call-template name="xsum">
                    <xsl:with-param name="currnode" select="$currnode/following-sibling::Row[1]"/>
                    <xsl:with-param name="attr-type" select="$attr-type"/>
                    <xsl:with-param name="res" select="$res + number(translate($currnode/@*[name() = $attr-type],',','.'))"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="format-number($res + number(translate($currnode/@*[name() = $attr-type],',','.')), '#,##','da-DK')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

Virker... Jeg havde simpelthen valgt den forkerte node at starte med...

arne_v>> Læg et svar! Som altid super godt svar :o)
Avatar billede arne_v Ekspert
20. januar 2010 - 20:37 #8
OK
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester