XSLT专业站 - 提供xslt和xml相关的资料书籍和教程  
XSLT专业站 - 提供xslt和xml相关的资料书籍和教程
网站地图  收藏本站
首页 | 热门文章 | 精彩实例 | 经典教程 | XSLT语法详解 | 资料下载 | 休闲天地 | 交流论坛
  当前位置:首页>热门文章>XSLT>文章内容
从 XSLT 样式表调用 JavaScript
来源:XSLT.org.cn 作者:XSLT专业站 发布时间:2007-08-04  
从 XSLT 样式表调用 JavaScript

XSLT 样式表允许您非常自由地操作原始 XML 文档中的数据。然而,有时候,当真正想进行一些实际编程时,XSLT 建议书设计成通过使用扩展允许这样做。这些扩展采用函数和元素的形式,可以使用处理器支持的任何语言编写。选择之一是将 JavaScript 直接或作为外部文件嵌入样式表。

这篇技巧文章使用 Apache Project 的 Xalan Java 2 转换引擎及其实现(请参阅 参考资料)。总体概念对于任何实现都是相同的,XSLT 建议书并未要求任何特殊实现方法。除了 Xalan,在您的 CLASSPATH 上包含还需要 js.jar 文件(参阅 参考资料),它包含了 JavaScript 实现,还需要 bsf.jar 文件,它是 Xalan 发行版的一部分。

源文档

样式表文档示例记载了猜数游戏中的项,其中猜数者从 1 到 100 猜三个数。样式表获取这三个数并将它们与随机数进行比较。样本文档含有两组猜测数:


样本文档
<?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() 方法返回,这就是一个可以使用典型 DOM 操作的典型 XML 节点。


图 2. 最终输出
最终输出 

参考资料



标题: 从 XSLT 样式表调用 JavaScript
关键字:样式 函数 元素 扩展 处理器 rules
上一篇:用节点集计数   下一篇:根据 XML 内容设置 XSL 样式表
  XSLT热点文章
·使用 XSLT 转换属性
·用节点集计数
·使用 XSLT 进行断行
·使用 Java 和 XSLT 生成动态 Web
·JSP结合XML+XSLT将输出转换HTML
  XSLT相关文章
·用节点集计数
·使用 XSLT 转换属性
·使用 XSLT 进行断行
·使用 Java 和 XSLT 生成动态 Web
·JSP结合XML+XSLT将输出转换HTML
Copyright© 2007 xslt.org.cn All rights reserved.