xslt计数循环
XSLT已经完成 。 这意味着只要有足够的内存,XSLT就可以计算任何其他图灵完备的语言(例如C ++)可以计算的任何东西。 对于习惯于更传统语言的程序员来说,这有点令人惊讶。 毕竟,XSLT缺少一些对许多算法都很重要的功能,包括循环和可变变量。
注意: XSLT所谓的变量在大多数其他语言中称为常量 。 与传统的编程变量相比,它们更像代数变量。
功能编程
刚才提到的遗漏不是疏忽。 XSLT是一种功能语言,而不是过程性语言。 在诸如C或Pascal的过程语言中,程序被定义为一系列步骤,按指定的顺序执行将产生最终结果,作为该顺序中的最后一步。 用功能语言将程序定义为由其他功能组成的功能,对其求值可得出最终结果。 函数式语言的最大优点是执行顺序无关紧要。 作为一个简单的示例,请考虑以下两个(代数)函数:
f(x) = 2*x
g(x) = x - 3
现在考虑函数h(x)
由f
和g
:
h(x) = f(g(x))
你可以评估这个函数或者g
第一:
h(x) = f(x - 3) = 2 * (x - 3) = 2x - 6
或f
首先:
h(x) = 2 * g(x) = 2 * (x - 3) = 2x - 6
两者产生相同的答案。 语言的功能性质使其更适合并行处理,因为可以同时评估程序的多个部分,而不用担心在其他部分之前需要评估哪个部分。 线程安全是自动的。
包括XSLT在内的功能语言不能包含传统循环,因为循环是按时间顺序排列的。 即,编写并编译一个典型的循环,使得i==1
必须在i==2
之前发生。 当然,您可以向后而不是向前运行循环,或者将循环计数器增加1以外的值,甚至可以像while
语句中那样完全消除循环计数器。 但是,无论循环的类型如何,执行的顺序都很重要,这与功能编程相反。
递归
在函数式语言中,大多数由传统语言中的循环完成的任务都由递归完成。 参数代替变量。 例如,最近我被问到如何在编译时不知道要打印的数字的情况下打印一定数量的点(句点)。 例如,在格式化餐厅菜单时,这可能会很有用,在菜单名称和价格之间通常需要不同数量的点:
Crawfish Etoufee.......$9.95
Fried Chicken..........$6.95
在C中,您将编写一个简单的函数,如下所示:
void printDots(int n) {
int i;
for (i = 0; i < n; i++) {
printf(".");
}
}
但是,这不是解决问题的唯一方法。 可以使用递归来代替循环,如下所示:
void printDotsRecursively(int n) {
if (n > 0) {
printf(".");
printDotsRecursively(n-1);
}
}
这在C语言中是不常见的。但是,在XSLT中,递归是唯一的选择。
下面的模板生成精确传入的点数作为count
参数的值。 逻辑很简单:如果$count
的值大于零,则输出一个句点并以一个count
参数减一的方式再次调用该函数。 否则,什么都不做。 这基本上是与printDotsRecursively
函数使用的算法相同的算法,只是它是在XSLT中而不是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>
例如,要打印100个点,可以使用100作为count
参数的值来调用模板:
<xsl:call-template name="dots">
<xsl:with-param name="count" select="100"/>
</xsl:call-template>
您可以传递一些其他值来计算要打印的点数,而不必传递恒定值。 例如,以下指令在考虑了价格的长度和主菜名称(更具体地说, price
和entree
的字符串值的长度)后,打印了将菜单行填充到80个字符所需的点数上下文节点的子元素):
<xsl:call-template name="dots">
<xsl:with-param name="count"
select="80 - string-length(entree) - string-length(price)"/>
</xsl:call-template>
摘要
无论是在C,XSLT还是Scheme中,用递归替换循环都需要一些习惯。 但是,这种技术具有一定的优雅性。 您不需要在XSLT中经常使用它,但是它使您可以完成棘手的任务,而这些任务是在标准XSLT中无法以其他方式完成的。
翻译自: https://www.ibm.com/developerworks/xml/library/x-tiploop/index.html
xslt计数循环