Announcement

Collapse
No announcement yet.

Template erstellen

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

  • Template erstellen

    Hallo Forum,

    ich stehe vor einem Problem und wäre für eure Hilfe sehr dankbar.

    Gegeben (test.xml):
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="test.xsl"?>
    <decimals>
        <decimal>137</decimal>
        <decimal>135</decimal>
        <decimal>132</decimal>
        <decimal>136</decimal>
        <decimal>138</decimal>
        <decimal>132</decimal>
        <decimal>134</decimal>
        <decimal>134</decimal>
        <decimal>131</decimal>
        <decimal>139</decimal>
        <decimal>136</decimal>
        <decimal>133</decimal>
        <decimal>133</decimal>
        <decimal>138</decimal>
        <decimal>134</decimal>
        <decimal>135</decimal>
        <decimal>136</decimal>
        <decimal>137</decimal>
    </decimals>
    Gesucht:
    Ich würde gerne ein Template erstellen, welches von jedem Wert <decimal> die Wurzel zieht und den durchschnittlichen Wert ausgibt.

    Bisher hab ich es geschafft Wurzeln zu berechnen oder die Anzahl zu berechnen:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"
        xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="2.0"
        xmlns:math="http://exslt.org/math" extension-element-prefixes="math">
    
        <xsl:template match="decimals">
            <html>
                <body>
                    Summe: <xsl:value-of select="sum(//decimal)"/>
                    <br/>
                    Anzahl: <xsl:value-of select="count(//decimal)" />
                    <br/>
                    Durchschnitt: <xsl:value-of select="sum(//decimal) div count(//decimal)" />
                    <br/>
                    Wurzel:
                    <xsl:for-each select="//decimal">
                        <xsl:call-template name="sqrt">
                            <xsl:with-param name="number" select="." />  
                        </xsl:call-template>
                    </xsl:for-each>
                    
                </body>            
            </html>
        </xsl:template>
        
        <xsl:template name="count">
            <xsl:param name="count" select="0" />
            <xsl:param name="sqr" select="0" />
            <xsl:call-template name="count" >
                <xsl:with-param name="count" select="$count +1" />
            </xsl:call-template> 
        </xsl:template>
        
        <xsl:template name="sqrt">
            <!--  The number you want to find the square root of  -->
            <xsl:param name="number" select="0" />
            <!--  The current 'try'.  This is used internally.  -->
            <xsl:param name="try" select="1" />
            <!--  The current iteration, checked against maxiter to limit loop count  -->
            <xsl:param name="iter" select="1" />
            <!--  Set this up to ensure against infinite loops  -->
            <xsl:param name="maxiter" select="10" />
     
            <xsl:choose>
                <xsl:when test="$try * $try = $number or $iter > $maxiter">
                    <xsl:value-of select="$try" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="sqrt">
                        <xsl:with-param name="number"
                            select="$number" />
                        <xsl:with-param name="try"
                            select="$try - (($try * $try - $number) div (2 * $try))" />
                        <xsl:with-param name="iter"
                            select="$iter + 1" />
                        <xsl:with-param name="maxiter"
                            select="$maxiter" />
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
        
    </xsl:stylesheet>
    Ausgabe:
    Code:
    Summe: 2430
    Anzahl: 18
    Durchschnitt: 135
    Wurzel: 11.70469991071962611.6189500386222511.48912529307605711.66190378969060111.7473401244707311.48912529307605711.57583690279022511.57583690279022511.44552314225959811.78982612255159511.66190378969060111.53256259467079711.53256259467079711.7473401244707311.57583690279022511.6189500386222511.66190378969060111.704699910719626
    Für eure Hilfe wäre ich sehr dankbar
    Gruß Michael

  • #2
    Eine Lösung bezogen auf die gruppierten und sortierten Einzelwerte:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:fn="http://www.w3.org/2005/xpath-functions"
      xmlns:tm="http://www.datenverdrahten.de/tm"
      exclude-result-prefixes="fn tm">
    
      <xsl:include href="tm_mathlib.xsl"/>
      <!-- Quelle: http://datenverdrahten.de/xslt2/tm_mathlib.xsl -->
    
      <xsl:template match="decimals">
      
        <html><head><title>Test</title></head><body>
    
          <xsl:for-each-group select="decimal" group-by=".">
            <xsl:sort select="." order="ascending" data-type="number"/>
    
            <xsl:for-each select=".">
              <dl>
                <dt>Wert: <xsl:value-of select="."/></dt>
                <dd>Wurzel: <xsl:value-of select="tm:sqrt(.)"/></dd>
                <dd>Anzahl: <xsl:value-of select="fn:count(../decimal[. = current()])"/></dd>
                <dd>Summe: <xsl:value-of select="fn:sum(../decimal[. = current()])"/></dd>
                <dd>Mittelwert: <xsl:value-of select="fn:avg(../decimal[. = current()])"/></dd>
              </dl>
            </xsl:for-each>     
    
          </xsl:for-each-group>
    
        </body></html>
      
      </xsl:template>
    
    </xsl:stylesheet>
    Hinweise: XPath 2.0 stellt für den Mittelwert fn:avg() zur Verfügung. Für die Wurzelwerte habe ich meine kleine Mathematik-Bibliothek verwendet, Ergebnisse offenbar wie bei Deinem sqrt-Template.

    Comment


    • #3
      Statt
      Code:
      count(../decimal[. = current()])
      reicht
      Code:
      count(current-group())
      und statt
      Code:
      sum(../decimal[. = current()])
      entsprechend
      Code:
      sum(current-group())

      Comment


      • #4
        Danke für die Ergänzung.

        Comment


        • #5
          Hallo,

          vielen Dank für die Antworten. Ich hab mich aber leider nicht richtig ausgedrückt.

          Ich versuche mein Problem nochmal zu schildern:

          Ich möchte von jedem Wert <decimal> die Wurzel ziehen, aber nur den Durchschnittswert ausgeben.
          Ich müsste also erst mal jeden Wurzelwert aufsummieren und dann durch die Anzahl teilen.

          Ich probiere es die ganze Zeit mit einer Rekursion, es will mir aber nicht gelingen.

          Mein Ansatz:
          Code:
          	<xsl:template name="rechne">
          		<xsl:param name="liste" select="0"/>
          		<xsl:choose>
          			<xsl:when test="$liste">
          					<xsl:variable name="summe">
          						<xsl:call-template name="rechne">
          							<xsl:with-param name="liste" select="$liste[position()!=1]"/>
          						</xsl:call-template>
          				</xsl:variable>
          				<xsl:value-of select="$summe +tm:sqrt($liste)"/>
          			</xsl:when>
          			<xsl:otherwise>0</xsl:otherwise>
          		</xsl:choose>
          	</xsl:template>
          schlägt leider immer fehl (Typ-Fehler).

          Ich bin mir schon am Haare ausreisen. Könnte mir nochmal jemand helfen?

          Gruß Micha

          Comment


          • #6
            Also der Mittelwert aller Wurzeln:
            Code:
            <xsl:template match="decimals">
              <xsl:value-of select="fn:avg(for $d in decimal return tm:sqrt($d))"/>
            </xsl:template>

            Comment

            Working...
            X