这篇技巧文章使用 Apache Project 的 Xalan Java 2 转换引擎及其实现(请参阅 参考资料)。总体概念对于任何实现都是相同的,XSLT 建议书并未要求任何特殊实现方法。除了 Xalan,在您的 CLASSPATH
上包含还需要 js.jar 文件(参阅 参考资料),它包含了 JavaScript 实现,还需要 bsf.jar
文件,它是 Xalan 发行版的一部分。
样式表文档示例记载了猜数游戏中的项,其中猜数者从 1 到 100 猜三个数。样式表获取这三个数并将它们与随机数进行比较。样本文档含有两组猜测数:
|
使用扩展元素或函数的第一步是定义要执行的代码。这涉及为代码定义新的名称空间及容器:
<? xml version="1.0" ?>
< xsl:stylesheet xmlns:xsl ="http://www.w3.org/1999/XSL/Transform"
xmlns:lxslt ="http://xml.apache.org/xslt"
xmlns:result ="http://www.example.com/results"
extension-element-prefixes ="result"
version ="1.0" >
< lxslt:component prefix ="result" elements ="rules" functions ="getResult" >
< lxslt:script lang ="javascript" >
function getResult (thisGuess) {
var thisResult = parseInt(Math.random()*100);
if (thisResult == parseInt(thisGuess)) {
return "Correct!";
} else {
return "Wrong! The actual answer was "+thisResult+
", not "+thisGuess+".";
}
}
</ lxslt:script >
</ lxslt:component >
< xsl:template match ="/" >
< xsl:apply-templates />
</ xsl:template >
</ xsl:stylesheet >
表面上,这是一个添加了两个新名称空间的典型样式表。第一个名称空间的前缀是 lxslt
,告诉处理器哪个元素定义了新功能。第二个名称空间的前缀是 result
,表明对新功能的一次调用。最后, extension-element-prefixes
属性让处理器知道哪个元素作为正常流的一部分不该被转换。(如同我们将看到的一样,它们仍然会返回一个值作为输出。)
组件本身指定从 result
名称空间前缀调用其内部的所有代码。它也让处理器知道哪些函数将从扩展元素调用,以及哪些函数将从扩展函数调用。脚本元素描述函数本身。
在这个例子中,我们从一个函数开始,该函数获取一个参数并将它与 1 到 100 间的随机数进行比较,返回一个表示结果的字符串。
在 XSLT 样式表中,扩展函数实际扩展 XPath,因此,您可以像使用内置函数(如 translate()
或 round()
)一样使用它们。
< xsl:template match ="/" >
< xsl:apply-templates />
</ xsl:template >
< xsl:template match ="entry" >
Guesser: < xsl:value-of select ="player" />
< xsl:apply-templates select ="guess" />
</ xsl:template >
< xsl:template match ="guess" >
Guess: < xsl:value-of select ="." />
Actual: < xsl:value-of select ="result:getResult(string(.))" />
</ xsl:template >
</ xsl:stylesheet >
本示例将当前节点( guess
)的字符串值传递给 getResult()
函数。名称空间让处理器知道触发结果组件中的函数。
扩展元素比函数要复杂一点。我们不希望扩展元素简单地返回一个值(虽然它们可以这样做),而希望它们在样式表处理过程中的特定“时刻”执行某个特定的操作。也不希望获得一个随机的参数列表(因为扩展函数也可以),扩展元素背后的代码含有两个良好定义的参数。
rules
元素触发 rules()
函数的处理。该函数将 rules
元素本身( elem
)作为其参数之一,允许您检索它拥有的任何定制属性的值。
扩展元素最强大的方面可能是通过 XSL 处理器上下文参数访问源文档本身的能力。
< lxslt:component prefix ="result" elements ="rules" functions ="getResult" >
< lxslt:script lang ="javascript" >
function rules(ctx, elem) {
ctxNode = ctx.getContextNode();
gameID = ctxNode.getFirstChild().getAttribute("gameID");
return "Contest "+gameID+" is based on "+
elem.getAttribute("guessType")+" guesses.";
}
</ lxslt:script >
</ lxslt:component >
rules
函数的第一个参数是 org.apache.xalan.extensions.XSLProcessorContext
对象形式的处理器上下文。这允许您检索代表上下文节点、整个源树、样式表以及当前执行转换的转换程序的对象。访问上下文节点是最常见的。一旦由 getContextNode()
方法返回,这就是一个可以使用典型 DOM 操作的典型 XML 节点。
原文地址:http://www.ibm.com/developerworks/cn/xml/tips/x-tipxsltjs/index.html