使用Xalan进行XSLT程序设计--使用Javascript及其他语言扩展XSL

本文介绍如何使用Xalan和JavaScript扩展XSLT的功能,包括自定义元素和函数,通过扩展增强XSLT的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Xalan支持使用Javascript及其他script语言扩展XSLT。由于其他语言例如NetRexx,BML,JPython,Jacl在国内应用不多,因此就不进行介绍了。而VBScript由于仅仅应用于Microsoft平台,因此也不进行介绍。对于perl扩展本文将少量的介绍。使用这些语言进行扩展需要使用由IBM提供的Bean Script Framework(BSF),使用Javascript扩展XSLT还需要安装Mozilla.org提供的javascript解释器Rhino。具体设置方法就是将js.jar文件设置进classpath。

由于XSLT本身提供的方法有限,因此有的时候我们需要自己编写函数进行扩展,另外,对于经常使用的扩展,apache-Xalan提供了一个扩展库,大家可以直接使用。

下面我们就开始介绍如何扩展XSL。在扩展XSL的时候我们可以扩展两种东西,第一是element第二是function。对于element的扩展我们可以理解为增加了具有新的功能的xslt元素。但是同基本的xslt元素不同的是,扩展元素可以进行扩展元素可以进行很多在xsl文件中没有表现出来的工作。实际上,我们在扩展element的时候实际上是定义了一个和这个element同名的函数。对于function的扩展我们可以理解为对xpath提供的函数的扩展。但是我们要在自己的名空间里面使用这些函数。扩展XSL基本可以分五步完成。

第一步是设定Xalan所使用的名空间。例如我们可以在xsl文件中通过下面的语句来完成上面的工作。<xsl:stylesheet xmlns:lxslt="http://xml.apache.org/xslt"/>。这里名空间的名字可以使用任意的名字但是url必须使用http://xml.apache.org/xslt,因为只有这样,xalan才能够识别出来它所使用的名空间。为了使用方便,我们在以后都将使用lxslt这个名字。

第二步是设定扩展所使用的名空间。我们可以通过下面的语句来完成。<xsl:stylesheet xmlns:my-ext"ext1"/>。这里可以使用任意的名字。

第三步是把扩展所使用的名空间设定为extension-element-prefixes。我们可以通过一下的xml代码完成。<xsl:stylesheet extension-element-prefixes="my-ext"/>。主意!上面所有的命令在真正使用的时候是要写道一个标签里面的。

第四步是用script写扩展元素与扩展方法。这一步有一些小小的技巧。我们需要仔细来讨论。首先我们来讨论如何把这些代码包含在一个tag里面。这里我们要使用如下的tag。

  &amp;lt;lxslt:component prefix=&amp;quot;prefix&amp;quot; functions=&amp;quot;func-1 func-2 ...func-n&amp;quot; elements=&amp;quot;elem-1 elem-2 ...elem-n&amp;quot;&amp;gt; &amp;lt;/lxslt:component&amp;gt; 

 

这里func-1等等是方法的名字,elem-1等等是扩展元素的名字。而在这个tag里面,我们又要包含一个tag书写真正的javascript代码。这个tag的使用如下面的例子。

  &amp;lt;lxslt:script lang=&amp;quot;javascript&amp;quot; &amp;gt; &amp;lt;!--The implementation script--&amp;gt; &amp;lt;/lxslt:script&amp;gt;

 

下面我们就开始讨论如何具体写扩展element和扩展function。首先我们来看看怎么写扩展element。在写一个扩展element之前,我们要在component标签中声明这个element。然后我们可以在script标签中定义一个和我们要扩展的element同名的javascript方法。这里借用了C语言中的声明和定义的概念,希望大家能够懂。例如我们又如下的xml文件,

  &amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt; &amp;lt;person sex=&amp;quot;m&amp;quot;&amp;gt;Bean&amp;lt;/person&amp;gt; 

我们要定义一个很无聊的标签,叫做out的,这个标签里除了完成标签内部所有的xsl命令之外还在最后加上一句"吃了吗"。呵呵,这个标签应该是无聊道极点了,但是应该能够让大家看懂是怎么回事。定义这个element的code如下。

 

  &amp;lt;lxslt:component prefix=&amp;quot;my-ext&amp;quot; elements=&amp;quot;out&amp;quot; functions=&amp;quot;displaySex&amp;quot;&amp;gt; &amp;lt;lxslt:script lang=&amp;quot;javascript&amp;quot;&amp;gt; function out(xslProcessorContext, elem){ var o = elem.getChildNodes(); var oTransformer = xslProcessorContext.getTransformer(); try{ for(var i = 0 ; i &amp;amp;lt; o.getLength() ; i ++ ){ o.item(i).execute( oTransformer ); } }catch( e ){ return e; } return &amp;quot;,吃了吗?&amp;quot;; } &amp;lt;/lxslt:script&amp;gt; &amp;lt;/lxslt:component&amp;gt;

 

在这里面我们看到定义了一个叫做out的方法,然后这里面又两个参数,其原型分别是org.apache.xalan.extensions.XSLProcessorContext和org.apache.xalan.templates.ElemExtensionCall。大家可以参考他们的javadoc文档,这里就不进行介绍了。函数内部的实现也很简单,我认为大家如果从aelfred学习道这里掌握这些东西是没有什么问题的。下面我们介绍关于定义一个扩展方法的知识。
扩展方法同扩展element的定义方法差不多,只是没有了必须要定义的参数,而且参数由自己来控制。例如我们下面定义的方法可以从参数获取性别,然后返回适当的称呼。

 &amp;lt;lxslt:component prefix=&amp;quot;my-ext&amp;quot; elements=&amp;quot;out&amp;quot; functions=&amp;quot;displaySex&amp;quot;&amp;gt; &amp;lt;lxslt:script lang=&amp;quot;javascript&amp;quot;&amp;gt; function out(xslProcessorContext, elem){ var o = elem.getChildNodes(); var oTransformer = xslProcessorContext.getTransformer(); try{ for(var i = 0 ; i &amp;amp;lt; o.getLength() ; i ++ ){ o.item(i).execute( oTransformer ); } }catch( e ){ return e; } return &amp;quot;,吃了吗?&amp;quot;; } function displaySex( sex ){ var sexStr = new String(sex.item(0).getNodeValue()); if( &amp;quot;m&amp;quot; == sexStr ) return &amp;quot;先生&amp;quot;; else if( &amp;quot;f&amp;quot; ==sexStr ) return &amp;quot;女士&amp;quot;; else return new String(sex.item(0).getNodeValue()); } &amp;lt;/lxslt:script&amp;gt; &amp;lt;/lxslt:component&amp;gt; 

第五步是在xsl文件中调用扩展方法。相对于上面的内容,调用就简单的多了。下面的代码给出了如何调用。

 &amp;lt;xsl:template match=&amp;quot;person&amp;quot;&amp;gt; &amp;lt;result&amp;gt;&amp;lt;my-ext:out&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;my-ext:displaySex(@sex)&amp;quot;/&amp;gt;你好&amp;lt;/my-ext:out&amp;gt;&amp;lt;/result&amp;gt; &amp;lt;/xsl:template&amp;gt; 

下面我们给出完整的xsl文件。

 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;GB2312&amp;quot;?&amp;gt; &amp;lt;xsl:stylesheet xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot; version=&amp;quot;1.0&amp;quot; xmlns:lxslt=&amp;quot;http://xml.apache.org/xslt&amp;quot; xmlns:my-ext=&amp;quot;ext1&amp;quot; extension-element-prefixes=&amp;quot;my-ext&amp;quot;&amp;gt; &amp;lt;xsl:output encoding=&amp;quot;GB2312&amp;quot;/&amp;gt; &amp;lt;lxslt:component prefix=&amp;quot;my-ext&amp;quot; elements=&amp;quot;out&amp;quot; functions=&amp;quot;displaySex&amp;quot;&amp;gt; &amp;lt;lxslt:script lang=&amp;quot;javascript&amp;quot;&amp;gt; function out(xslProcessorContext, elem){ var o = elem.getChildNodes(); var oTransformer = xslProcessorContext.getTransformer(); try{ for(var i = 0 ; i &amp;amp;lt; o.getLength() ; i ++ ){ o.item(i).execute( oTransformer ); } }catch( e ){ return e; } return &amp;quot;,吃了吗?&amp;quot;; } function displaySex( sex ){ var sexStr = new String(sex.item(0).getNodeValue()); if( &amp;quot;m&amp;quot; == sexStr ) return &amp;quot;先生&amp;quot;; else if( &amp;quot;f&amp;quot; ==sexStr ) return &amp;quot;女士&amp;quot;; else return new String(sex.item(0).getNodeValue()); } &amp;lt;/lxslt:script&amp;gt; &amp;lt;/lxslt:component&amp;gt; &amp;lt;xsl:template match=&amp;quot;person&amp;quot;&amp;gt; &amp;lt;result&amp;gt;&amp;lt;my-ext:out&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;my-ext:displaySex(@sex)&amp;quot;/&amp;gt;你好&amp;lt;/my-ext:out&amp;gt;&amp;lt;/result&amp;gt; &amp;lt;/xsl:template&amp;gt; &amp;lt;/xsl:stylesheet&amp;gt; 
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值