Using recursion to implement loops in XSLT

Source: Internet
Author: User
Tags execution final printf xsl xslt

XSLT is accomplished by Turing (Turing complete). That is, if there is enough memory, XSLT can do the calculations that any other Turing completion language (such as C + +) can accomplish. This may be a bit odd for programmers who have more traditional language attributes. After all, XSLT lacks features that are extremely important to many algorithms, including loops and variable variables.

Note: The so-called variables in XSLT are called constants in most other languages. They are more like algebraic variables than traditional programming variables.

Functional programming

The omission is not due to negligence. XSLT is a functional language rather than a procedural language. In a procedural language such as C or Pascal, a program is defined as a series of steps that are executed in the order in which they are performed and produce the final result in the final step. In functional languages, a program is defined as a function composed of other functions, and the function evaluates to form the final result. The biggest advantage of functional languages is that the order of execution is irrelevant. As a simple example, consider the following two (algebraic) functions:

f(x) = 2*x
g(x) = x - 3

Set function h (x) is a composite function of f and G:

h(x) = f(g(x))

To evaluate the function, you can first compute g:

h(x) = f(x - 3) = 2 * (x - 3) = 2x - 6

You can also first calculate F:

h(x) = 2 * g(x) = 2 * (x - 3) = 2x - 6

The result of the two is the same. The function of a language makes it more appropriate for parallel processing, because multiple parts of the problem can be computed at the same time, without worrying that some of them are calculated before other parts. Thread safety is automatically implemented.

Functional languages include XSLT, but they cannot contain traditional loops, because loops are ordered in time. That is, a typical cycle must be written and compiled to ensure that I==1 appears before i==2. Of course, you can also reverse rather than forward the loop, or use a loop counter increment other than 1, or even completely cancel the loop counter like the while statement. But regardless of the type of loop, the order of execution is critical, as opposed to functional programming.

Recursion

In functional programming, most tasks that are performed in a traditional language with loops can be completed using recursive return. parameter instead of the variable. For example, someone recently asked me how to output dots (periods) that don't know the number at compile time. For example, you might want to use a Format menu because there are often different numbers of points between the name and the price of the dish:

Crawfish Etoufee.......$9.95
Fried Chicken..........$6.95

You can write a simple function in the C language:

void printDots(int n) {
  int i;
  for (i = 0; i < n; i++) {
   printf(".");
  }
 
}

But that is not the only way to solve the problem. You can replace loops with recursion, for example:

void printDotsRecursively(int n) {
  if (n > 0) {
   printf(".");
   printDots(n-1);
  }
 
}

This is rarely done in C, but in XSLT, this is the only way.

The following template accurately generates points for the number of numbers passed by the count parameter. The logic is simple: If the $count value is greater than 0, output a point, subtract the Count argument by 1 and then call the function; This is essentially the same as the algorithm used by the printdotsrecursively function, but it is implemented in XSLT rather than C:

 <xsl:template name="dots">
 
    <xsl:param name="count" select="1"/>
    <xsl:if test="$count > 0">
     <xsl:text>.</xsl:text>
     <xsl:call-template name="dots">
      <xsl:with-param name="count" select="$count - 1"/>
     </xsl:call-template>
    </xsl:if>
   
  </xsl:template>

For example, to output 100 points, call the function with the count parameter value:

  <xsl:call-template name="dots">
    <xsl:with-param name="count" select="100"/>
   </xsl:call-template>

If you do not want to pass a constant value, you can also calculate the number of points to print based on other data. For example, the following instruction calculates the length of the price and the name of the dish (more specifically, the value of the String-values function of the prices and entree elements in the context node), and the output is sufficient to populate each menu line to 80 characters:

  <xsl:call-template name="dots">
    <xsl:with-param name="count"
         select="80 - string-length(entree) - string-length(price)"/>
   </xsl:call-template>

Conclusion

Using recursion instead of loops is applied both in C, in XSLT, and in Scheme. But the technique is very elegant. There is no need to use this technique frequently in XSLT, but using this technique can accomplish a tricky task that no other standard XSLT technology could.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.