2008-12-03 12 views
10

Wie speichere ich die Iterationen, die in einem xsl: for-each aufgetreten sind? (Variablen in XSL sind unveränderlich)xsl: for-each Schleifenzähler

Mein Ziel ist es, die MAX-Anzahl der Kinder für jeden Knoten auf einer bestimmten Ebene zu finden.

Zum Beispiel könnte ich drucken möchten, dass es nicht mehr als 2 Response-Knoten für jede Frage in dieser Umfrage:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<?xml-stylesheet type="text/xsl" href="testing.xsl"?> 
<Survey> 
    <Question> 
    <Response text="Website" /> 
    <Response text="Print Ad" /> 
    </Question> 
    <Question> 
    <Response text="Yes" /> 
    </Question> 
</Survey> 

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:template match="/"> 
    <html> 
    <head> 
    </head> 
    <body> 
    <xsl:for-each select="Survey"> 
     The survey has <xsl:value-of select="count(child::Question)"/> questions. 
     <br /> 
     <xsl:variable name="counter">0</xsl:variable> 
     <xsl:for-each select="Question"> 
     <!-- TODO: increment the counter ??????? --> 
     </xsl:for-each> 
     No more than <xsl:value-of select="$counter"/> responses were returned for any question. 
    </xsl:for-each> 
    </body> 
    </html> 
</xsl:template> 
</xsl:stylesheet> 

Antwort

10

man nicht „die Iterationen speichern, die in einem xsl aufgetreten sind: for-each "weil XSLT is a functional language und Variablen sind unveränderlich.

Die folgende Transformation findet das gewünschte Maximum:

 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

    <xsl:template match="/"> 
     <xsl:call-template name="maximum"> 
     <xsl:with-param name="pNodes" select="*/Question"/> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="maximum"> 
     <xsl:param name="pNodes"/> 

     <xsl:variable name="vNumNodes" select="count($pNodes)"/> 

     <xsl:choose> 
     <xsl:when test="$vNumNodes = 1"> 
      <xsl:value-of select="count($pNodes[1]/Response)"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:variable name="vHalf" 
       select="floor($vNumNodes div 2)"/> 

      <xsl:variable name="vMax1"> 
      <xsl:call-template name="maximum"> 
      <xsl:with-param name="pNodes" 
       select="$pNodes[not(position() > $vHalf)]"/> 
      </xsl:call-template> 
      </xsl:variable> 

      <xsl:variable name="vMax2"> 
      <xsl:call-template name="maximum"> 
      <xsl:with-param name="pNodes" 
       select="$pNodes[position() > $vHalf]"/> 
      </xsl:call-template> 
      </xsl:variable> 

      <xsl:value-of select= 
      "$vMax1*($vMax1 >= $vMax2) + $vMax2*($vMax2 > $vMax1)"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

Wenn auf dem mitgelieferten XML-Dokument angewandt:

 
<Survey> 
    <Question> 
     <Response text="Website" /> 
     <Response text="Print Ad" /> 
    </Question> 
    <Question> 
     <Response text="Yes" /> 
    </Question> 
</Survey> 

das gewünschte Ergebnis produziert wird:

Sie folgendes beachten: Die Vorlagemaximum“ nennt sich rekursiv genannt und implementiert die DVC (Divide and Conquer principle) die Rekursion Stack-Tiefe zu minimieren. Die Liste der Knoten wird in zwei geteilt, die Maxima der beiden Listen werden berechnet (rekursiv) und der größere der beiden wird zurückgegeben.

Verwandte Themen