Announcement

Collapse
No announcement yet.

summieren aus string

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • summieren aus string

    Hallo,

    in einen Attribut zb. aa steht ein Textstring indem sich eine Zahl befindet diese bekomme ich relativ einfach mit den String operationen angezeigt. Nun meine Frage ist es möglich diesen inhalt der Attribute aufzusummieren in XSLT 1.0?

    wenn ich zb. Schreibe sum(substring(@aa,38,1)) wird ein Fehler ausgegeben.

  • #2
    Die Funktion sum() kann nur direkt auf Knotenmengen angewendet werden, z. B. auf alle @aa-Attributknoten. Die Summierung von Werten aus Teilstrings lässt sich über ein separates benanntes Template über rekursive xsl:call-template-Aufrufe erreichen.

    Comment


    • #3
      Danke, das klingt wieder sehr kompliziert für eine einfache Funktion,

      ich versuche grad JS in XSLT zu integrieren nur leider scheinen nicht alle Funktionen akzeptiert zu werden, gibt es da vielleicht bibliotheken die man noch integrieren muss oder irgendwelche Einschränkunen danke im voraus.

      der substring() befehl funktioniert zb nicht genauso wie indexof woran kann das liegen?

      Codeschnipsel
      Code:
      <xsl:stylesheet xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:usr="urn:custom-javascript" xmlns:z="#RowsetSchema" version="1.0" exclude-result-prefixes="xsl ddwrt msxsl" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:date="http://exslt.org/dates-and-times" xmlns:str="http://exslt.org/strings" extension-element-prefixes="date str">
      
      
      <ms:script language="JScript" implements-prefix="usr">
          <![CDATA[
          function processEquation(ops) {
            var result=0, i;
            var tt = ops.substring(5,7)
             return tt;
          }
          ]]>
        </ms:script>

      Comment


      • #4
        Was soll denn erreicht werden? Was funktioniert nicht mit substring()? Zeige ansonsten mal ein Stück vom XML mit den zu summierenden Attributen.

        Comment


        • #5
          Fehlermeldung im Browser Fenster (Internet Explorer 6) lautet:
          Laufzeitfehler in Microsoft JScript Das Objekt unterstützt diese Eigenschaft oder Methode nicht. Zeile = 4, Spalte = 6 (Zeil...


          ich habe im Prinzip einen String mit mehreren Zahlen ich brauche einzelne Zahlen aus diesen String um die den Durschnitt zu bilden. Zb der durchschnitt aller Zahlen von Motivation oder Faktoren.

          allerdings bekomme ich leider schon eine Fehlermeldung wen ich substring im Javascript verwende. Der Fehler warum der Befehl nicht funktioniert würde mir schon ausreichen denke den Rest bekomme ich dann schon hin

          Danke


          die xsl Datei:
          Code:
          <?xml version="1.0" encoding="utf-8" ?>
          <xsl:stylesheet xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:usr="urn:custom-javascript" xmlns:z="#RowsetSchema" version="1.0" exclude-result-prefixes="xsl ddwrt msxsl" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:date="http://exslt.org/dates-and-times" xmlns:str="http://exslt.org/strings" extension-element-prefixes="date str">
              <xsl:output method="html" indent="no"/>
          	
          	<ms:script language="JScript" implements-prefix="usr">
              <![CDATA[
              function processEquation(ops) {
                var result=0, i;
                var tt = ops.substring(13,14)
                 return tt;
              }
              ]]>
            </ms:script>
          	   
          	<xsl:template match="/">
          	result: <xsl:value-of select="usr:processEquation(.//rs:data/z:row/@ows_Personen)"/>		
          	</xsl:template>
          </xsl:stylesheet>

          aussschnitt aus der xml
          Code:
          <?xml-stylesheet href="survey.xsl" type="text/xsl"?> 
              <rs:data ItemCount="5">
              <z:row ows_Personen="Motivation;#1#Faktoren;#1#/>
              <z:row ows_Personen="Motivation;#5#Faktoren;#2# />
          <z:row ows_Personen="Motivation;#3#Faktoren;#2# />
          
            </rs:data>
          </xml>
          Zuletzt editiert von chris.ba; 19.02.2009, 16:07.

          Comment


          • #6
            Ich habe den Fehler gefunden, der übergebene Wert aus der XML Datei ist kein String, leider weis ich nicht welcher Art er ist wie finde ich sowas heraus und wie kann man eine TypenKonversion machen? String() funktioniert ebenfals leider nicht.

            Comment


            • #7
              ok ich habs danke, mit String() in xslt kann ich das als String übergeben nun klappt es...

              Interesant wäre zu wissen welcher Datentyp Standartmäßig übergeben wird?

              Comment


              • #8
                Zeichenketten sollten als String und numerische Inhalte als Number übergeben werden. Hier mal noch die rekursive XSLT-Lösung (JavaScript könnte im Browser auch deaktiviert sein oder wird serverseitig prozessiert?):
                Code:
                <xsl:template match="rs:data">
                  <xsl:call-template name="summe">
                    <xsl:with-param name="s" select="0"/>
                    <xsl:with-param name="i" select="1"/>
                    <xsl:with-param name="max" select="count(z:row[@ows_Personen])"/>
                  </xsl:call-template>
                </xsl:template>
                
                <xsl:template name="summe">
                  <xsl:param name="s" select="$s"/>
                  <xsl:param name="i" select="$i"/>
                  <xsl:param name="max" select="$max"/>
                
                  <xsl:choose>
                    <xsl:when test="$i &lt;= $max">
                      <xsl:call-template name="summe">
                        <xsl:with-param name="s" select="$s + number(substring(z:row[$i]/@ows_Personen,13,1))"/>
                        <xsl:with-param name="i" select="$i + 1"/>
                        <xsl:with-param name="max" select="$max"/>
                      </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                       <xsl:text>Summe = </xsl:text><xsl:value-of select="$s"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:template>
                Aus Deinem Beispiel-XML-Code ergibt sich Summe = 9 (aus 1, 5 und 3).

                Comment


                • #9
                  Es wird Serverseitig prozessiert, allerdings gibt es nun das Problem das ich deswegen keine Globalen Variablen verwenden kann und nun wohl doch auf eine XSLT Lösung zurückgreifen muss.

                  Vielen Dank für dein Codestück, allerdings wenn ich es vorab in Saxon laufen lasse meldet er den Fehler das die 3 Variablen (im template summe) nicht definiert seien.

                  Comment


                  • #10
                    Das Problem kann ich mit Saxon B 9.1.0.5 nachvollziehen (Error XPST0008). Hatte zuvor mit der Standalone-EXE von AltovaXML 2009 problemlos getestet. Wenn auf dem Server allerdings XSLT 2.0 möglich ist (eine aktuelle Saxon-Version spricht dafür), dann wäre diese Umsetzung kürzer und eleganter (roter Code):

                    Code:
                    <?xml version="1.0" encoding="UTF-8"?>
                    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                     xmlns:rs="urn:schemas-microsoft-com:rowset"
                     xmlns:z="#RowsetSchema"
                     xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn rs z">
                    
                    <xsl:template match="rs:data">
                      <xsl:text>Summe = </xsl:text>
                      <xsl:value-of select="fn:sum(for $str in z:row/@ows_Personen return number(fn:substring($str,13,1)))"/>
                    </xsl:template>
                    
                    </xsl:stylesheet>
                    Nachtrag zur xsl:call-template-Variante:
                    Wenn die verwendeten Parameter global definiert werden (direkt unterhalb von xsl:stylesheet), spielt auch Saxon mit:
                    Code:
                    <xsl:stylesheet ...>
                      <xsl:param name="s"/>
                      <xsl:param name="i"/>
                      <xsl:param name="max"/>
                      <!-- ... -->
                    </xsl:stylesheet>
                    Zuletzt editiert von Thomas Meinike; 20.02.2009, 16:22.

                    Comment


                    • #11
                      Leider kann ich nur mit XSLT 1.0 arbeiten.

                      ich habe das jetzt gelöst wahrscheinlich etwas umständlich aber es funktioniert.

                      Code:
                      <xsl:template name="loop"> 
                      			<!-- Parameter für den Schleifendurchlauf --> 
                      			<xsl:param name="from">0</xsl:param> 
                      			<xsl:param name="i" select="1"/>
                      			<xsl:param name="inc">1</xsl:param> 
                      			<xsl:param name="to"/> 
                      			<xsl:param name="summe">0</xsl:param>
                      			<xsl:param name="grp2"/>			
                      			<!-- Rekursiver Aufruf des Templates --> 
                      			<xsl:if test="$from &lt; $to"> 
                      				<xsl:call-template name="loop"> 
                      					<xsl:with-param name="from" select="$from+$inc"/> 
                      					<xsl:with-param name="inc" select="$inc"/> 
                      					<xsl:with-param name="to" select="$to"/>
                      					<xsl:with-param name="i" select="$i+1"/>
                      					<xsl:with-param name="summe" select="$summe + number(substring(z:row[$i]/@ows_Personen,38,1))"/>
                      				</xsl:call-template> 
                      			</xsl:if>
                      			<xsl:if test="$from = $to">
                      				<tr></tr>
                      				<tr><xsl:value-of select="$summe div count(z:row[@ows_Personen])"></xsl:value-of></tr>
                      			</xsl:if>
                      		</xsl:template> 
                      
                      		
                      
                      
                          <xsl:template match="rs:data">	
                          	<xsl:call-template name="Style" />
                              <table width="100%">		
                      			<xsl:call-template name="loop">
                      				<xsl:with-param name="from">1</xsl:with-param> 
                      				<xsl:with-param name="to" select="count(z:row[@ows_Personen])+1"></xsl:with-param>
                      			</xsl:call-template>
                      		</table>	
                          </xsl:template>
                      Ist es möglich so eine rekursion nochmals rekursiv aufzurufen?

                      also das er erst die ersten zahlen für jede z:row zusammenzählt und danach die zweiten usw.

                      oder ist ein zweimaliger rekursiver Aufruf nicht möglich?

                      Comment


                      • #12
                        Man kann benannte Template durchaus mehrfach aufrufen, es hängt letzlich von den übergebenen Parametern und geeigneten Bedingungen ab, um sich keine Endlos-Rekursion einzuhandeln.

                        Comment

                        Working...
                        X