除了开发语言换成了javascript 外,其它流程和 saxon 的版本还是挺像的。所以就不再详细解释了。
不过值得一提的是,光有javascript还是不够的。在 xalan 版本中,细心的人一定会发现,真正起作用的部分,实际上是一个名字为 PrintWriter 的 java 类。也就是说 javascript 实际上只是一个流程控制者,正是依靠着 java sdk 强大的类库,XSLT 才能如虎添翼,去完成不可能的任务。
那么是不是只有自己写扩展才能解决问题呢?答案当然是否定的。saxon和xalan早就为我们预制了很多公用的扩展功能。我们只要采用拿来主义就可以了。下面我以数据库扩展为例,进一步向你展示XSLT扩展的魅力。
采用 saxon 引擎时,我们引入了几个新的 XSLT 扩展元素,例如 sql:connect,sql:query。通过这些扩展元素,我们可以连接数据库,并执行查询。
比如在下例中,我们可以利用 saxon 提供的 sql 扩展去访问 Informix 数据库。步骤如下:首先我们利用sql:connect建立和数据库的连接,连接使用的参数预先已经定义好了。
其次,我们用sql:query进行查询。查询的字段和查询的条件,均以参数的形式出现。
查询成功之后,利用标准的XSLT元素进行格式解析,并生成HTML格式的表格。
最后,通过sql:close关闭连接。至此整个处理结束。
foo_sql_query.xml
<?xml version="1.0"?>
<query>
<table>FOO</table>
<columns>username,birthdate</columns>
<condition/>
</query>
foo_sql_saxon_query.xsl
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:sql="java:/net.sf.saxon.sql.SQLElementFactory"
xmlns:saxon="http://saxon.sf.net/"
extension-element-prefixes="saxon sql">
<xsl:param name="driver" select="'com.informix.jdbc.IfxDriver'"/>
<xsl:param name="database"
select="'jdbc:informix-sqli://192.168.0.1:5000/testDB:
INFORMIXSERVER=pcsnet;user=pcs;password=abc'"/>
<xsl:param name="user" select="'pcs'"/>
<xsl:param name="password" select="'abc'"/>
<xsl:template match="/">
<xsl:variable name="connection" as="java:java.sql.Connection"
xmlns:java="http://saxon.sf.net/java-type">
<sql:connect driver="{$driver}" database="{$database}" user="{$user}"
password="{$password}"/>
</xsl:variable>
<HTML>
<HEAD>
Table of <xsl:value-of select="/query/table"/>
</HEAD>
<BODY>
<TABLE border="1">
<xsl:variable name="dbtable">
<sql:query connection="$connection" table="{/query/table}"
column="{/query/columns}"/>
</xsl:variable>
<TR>
<xsl:if test="string-length(/query/columns)>0">
<xsl:call-template name="getcolumns">
<xsl:with-param name="columns" select="/query/columns"/>
</xsl:call-template>
</xsl:if>
</TR>
<xsl:apply-templates select="$dbtable/row"/>
<xsl:text>
</xsl:text>
</TABLE>
</BODY>
</HTML>
<sql:close connection="$connection"/>
</xsl:template>
<xsl:template name="getcolumns">
<xsl:param name="columns"/>
<xsl:if test="string-length($columns)>0">
<TH>
<xsl:choose>
<xsl:when test="contains($columns,',')">
<xsl:value-of select="substring-before($columns,',')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$columns"/>
</xsl:otherwise>
</xsl:choose>
</TH>
<xsl:call-template name="getcolumns">
<xsl:with-param name="columns" select="substring-after($columns,',')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="row-set">
<xsl:apply-templates select="row"/>
</xsl:template>
<xsl:template match="row">
<TR>
<xsl:apply-templates select="col"/>
</TR>
</xsl:template>
<xsl:template match="col">
<TD>
<xsl:value-of select="text()"/>
</TD>
</xsl:template>
</xsl:stylesheet>
