xslt
本技巧使用Apache Project的Xalan Java 2转换引擎及其实现(请参阅参考资料 )。 总体概念对于任何实现都是相同的,但是XSLT建议并不强制要求任何特定的实现方法。 除了Xalan的,您需要js.jar文件(参见相关信息 ),其中包含JavaScript实现,你的CLASSPATH
,以及bsf.jar
,这是Xalan的发行版的一部分。
源文件
示例样式表记录了一个猜谜游戏中的条目,其中玩家进行了3个1到100的猜测。样式表接受了这3个猜测并将它们与随机数进行比较。 该示例文档包含两组猜测:
样本文件
<?xml version="1.0"?>
<entries gameID="DWO">
<entry>
<player>John</player>
<guess>3</guess>
<guess>9</guess>
<guess>222</guess>
</entry>
<entry>
<player>Mary</player>
<guess>88</guess>
<guess>76</guess>
<guess>5</guess>
</entry>
</entries>
创建组件
使用扩展元素或功能的第一步是定义要执行的代码。 这涉及为代码定义新的名称空间和容器:
基本样式表
<?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()
函数。 命名空间使处理器知道触发结果组件中的功能。
图1.初步结果
使用元素
扩展元素比功能要复杂一些。 它们不是简单地返回一个值(尽管可以返回),而是旨在在样式表的处理过程中的特定“时间”执行特定的动作。 此外,扩展元素后面的代码没有像扩展函数那样获取任意参数列表,而是具有两个定义明确的参数。
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()
方法返回,这就是一个典型的XML节点,并具有典型的DOM操作。
图2.最终输出
翻译自: https://www.ibm.com/developerworks/xml/library/x-tipxsltjs/index.html
xslt