4

I am trying to create a loop inside a template. I found 2 methods, but both of them did not work:

Method 1:

<xsl:template name="recurse_till_ten">
    <xsl:param name="num">1</xsl:param> <!-- param has initial value of
1 -->
    <xsl:if test="not($num = 10)">
        ...do something
        <xsl:call-template name="recurse_till_ten">
            <xsl:with-param name="num">
                <xsl:value-of select="$num + 1">
            </xsl:with-param>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

Method 2:

<xsl:variable name="count" select="'5'"/> 
<xsl:for-eachselect="(//*)[position()&lt;=$count]"> 
 <!-- Repeated content Here --> 
 <!-- use position() to get loop index --> 
 <xsl:value-of select="position()"/>.<br/> 
</xsl:for-each>

Method 1 gave the following error:

element template only allowed as child of stylesheet

Method 2 did not show anything since I am using another position() for displaying some outputs:

<td>
        <xsl:if test='buildid = /cdash/etests/etest/buildid'>
                            <xsl:variable name='index' 
                                          select='2*count(preceding-sibling::build[buildid = /cdash/etests/etest/buildid])+position()' />
                            <xsl:value-of select="/cdash/etests/etest[position()=$index]/value" />
        </xsl:if>
                        </td>

How can I create a loop that should call the code between two times?

Original XSL:

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

<xsl:include href="header.xsl"/>
<xsl:include href="footer.xsl"/>

<xsl:include href="local/header.xsl"/>
<xsl:include href="local/footer.xsl"/>

<xsl:output method="xml" indent="yes"  doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
   doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
<xsl:template match="/">
<html>
<head>
  <title><xsl:value-of select="cdash/title"/></title>
  <meta name="robots" content="noindex,nofollow" />
  <link rel="StyleSheet" type="text/css">
    <xsl:attribute name="href">
      <xsl:value-of select="cdash/cssfile"/>
    </xsl:attribute>
  </link>
  <xsl:call-template name="headscripts"/>
   <!-- Include JavaScript -->
  <script src="javascript/cdashTestGraph.js" type="text/javascript" charset="utf-8"></script>

</head>
<body bgcolor="#ffffff">

<xsl:choose>
<xsl:when test="/cdash/uselocaldirectory=1">
  <xsl:call-template name="header_local"/>
</xsl:when>
<xsl:otherwise>
  <xsl:call-template name="header"/>
</xsl:otherwise>
</xsl:choose>

<br/>
<h3>Testing summary for
<u><xsl:value-of select="cdash/testName"/></u>
 performed between <xsl:value-of select="cdash/builds/teststarttime"/> and <xsl:value-of select="cdash/builds/testendtime"/>
</h3>

<!-- Failure Graph -->
<a>
<xsl:attribute name="href">javascript:showtestfailuregraph_click('<xsl:value-of select="/cdash/dashboard/projectid"/>','<xsl:value-of select="/cdash/testName"/>','<xsl:value-of select="/cdash/builds/currentstarttime"/>')</xsl:attribute>
Show Test Failure Trend
</a>
<div id="testfailuregraphoptions"></div>
<div id="testfailuregraph"></div>
<center>
<div id="testfailuregrapholder"></div>
</center>
<br/>
<!-- Test Summary table count(preceding-sibling::etests[columnname]) + 1 count(/cdash/etests/columnname) + 1  /cdash/etests/columnname[position()=$index] -->
<table id="testSummaryTable" cellspacing="0" cellpadding="3" class="tabb">
<thead>
  <tr class="table-heading1">
    <th id="sort_0">Site</th>
    <th id="sort_1">Build Name</th>
    <th id="sort_2">Build Stamp</th>
    <th id="sort_3">Status</th>
    <th id="sort_4">Time (s)</th>
    <th id="sort_5">Build Revision</th>
    <xsl:for-each select='/cdash/etests/columnname'>
        <xsl:variable name='index_col' select='count(preceding-sibling::columnname) + 1'/>
        <th><xsl:attribute name="id">
            <xsl:value-of select="$index_col" />
        </xsl:attribute>
        <xsl:value-of select="/cdash/etests/columnname[position()=$index_col]" /></th>
    </xsl:for-each>



  </tr>
</thead>

<xsl:for-each select="cdash/builds/build">
  <tr>
    <td>
      <xsl:value-of select="site"/>
    </td>

    <td><a>
      <xsl:attribute name="href">
        <xsl:value-of select="buildLink"/>
      </xsl:attribute>
      <xsl:value-of select="buildName"/>
    </a></td>
    <td>
      <xsl:value-of select="buildStamp"/>
    </td>
    <td>
      <xsl:attribute name="class">
        <xsl:value-of select="statusclass"/>
      </xsl:attribute>
      <a>
      <xsl:attribute name="href">
        <xsl:value-of select="testLink"/>
      </xsl:attribute>
      <xsl:value-of select="status"/>
      </a>
    </td>
    <td>
      <xsl:value-of select="time"/>
    </td>
    <td>
      <a><xsl:attribute name="href"><xsl:value-of select="update/revisionurl"/></xsl:attribute>
         <xsl:value-of select="update/revision"/>
      </a>
    </td> 
    <!-- NEW ADDITIONNN !!!!!!!!!!! -->

        <td>
        <xsl:if test='buildid = /cdash/etests/etest/buildid'>
                            <xsl:variable name='index' 
                                          select='2*count(preceding-sibling::build[buildid = /cdash/etests/etest/buildid])+1' />
                            <xsl:value-of select="/cdash/etests/etest[position()=$index]/value" />
        </xsl:if>
                        </td>

        <td>
        <xsl:if test='buildid = /cdash/etests/etest/buildid'>
                            <xsl:variable name='index' 
                                          select='2*count(preceding-sibling::build[buildid = /cdash/etests/etest/buildid])+2' />
                            <xsl:value-of select="/cdash/etests/etest[position()=$index]/value" />
        </xsl:if>
                        </td>

    <!-- NEW ADDITIONNN !!!!!!!!!!! -->
  </tr>
</xsl:for-each>
</table>
<br/>

<!-- FOOTER -->
<br/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Original XML:

<?xml version="1.0" encoding="utf-8"?><cdash><title>Title</title><cssfile>cdash.css</cssfile><version>2.1.0</version><dashboard>
  <nextdate>2012-09-18</nextdate>
  </menu><etests>
<columnname>LoadTime</columnname>
<etest>
<name>LoadTime</name><buildid>19390</buildid><value>1777</value>
</etest>
<columnname>Median</columnname>
<etest>
<name>Median</name><buildid>19390</buildid><value>1508</value>
</etest>
<etest>
<name>LoadTime</name><buildid>19389</buildid><value>676</value>
</etest>
<etest>
<name>Median</name><buildid>19389</buildid><value>868</value>
</etest>
</etests>
<builds>
<projectid>1</projectid><currentstarttime>1347825600</currentstarttime><teststarttime>2012-09-16T22:00:00</teststarttime><testendtime>2012-09-17T22:00:00</testendtime>
<build>
<buildName>Linux</buildName><buildStamp>20120916-2100-Nightly</buildStamp><time>174.86</time><buildid>19390</buildid><buildLink>viewTest.php?buildid=19390</buildLink><testLink>testDetails.php?test=289784&amp;build=19390</testLink><status>Passed</status><statusclass>normal</statusclass></build>
<build>
<buildName>Linux</buildName><buildStamp>20120916-2100-Nightly</buildStamp><time>174.86</time><buildid>19389</buildid><buildLink>viewTest.php?buildid=19389</buildLink><testLink>testDetails.php?test=289784&amp;build=19389</testLink><status>Passed</status><statusclass>normal</statusclass></build>
</builds>
<generationtime>0.201</generationtime></cdash></xml>
www
  • 586
  • 1
  • 14
  • 29
  • The error in the first case indicates that the template is nested inside another template, which is invalid. You haven't shown the input XML and enough of the XSL to debug this (i.e. how you invoke the template and what the XSL context is at that point). – Jim Garrison Nov 02 '12 at 17:05
  • @JimGarrison Thank you for your reply. I edited the question and added required files... – www Nov 02 '12 at 18:02

1 Answers1

6

I'm not sure what you are trying to do in your method 2 process so I'm going to focus on the first one.

You will want to update the code to something like this

<xsl:template name="recurse_till_ten">
    <xsl:param name="num" />
    <xsl:if test="not($num = 10)">
        ...do something
        <xsl:call-template name="recurse_till_ten">
            <xsl:with-param name="num" select="$num + 1" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>

The only important change I made was not setting the variable in the loop. By setting it in the loop then you are always setting num = 1 which would make for an infinite loop.

So then you would call it somewhere else in your template by doing this.

<xsl:call-template name="recurse_till_ten">
    <xsl:with-param name="num" select="number('1')" />
</xsl:call-template>

That should allow you to loop until the variable hits 10.

Matthew Green
  • 10,161
  • 4
  • 36
  • 54