8.3 XSLT转换分类

前面看到的XSLT对XML的处理都是由浏览器完成的,我们只需要提供XML和XSLT样式定义文件,然后用浏览器打开该XML文档即可看到转换后的结果。这种转换是由客户端浏览器完成,也就是客户端转换。

8.3.1 客户端转换和服务器端转换

实际上,XSLT转换可分为如下两类:

alt 服务器端转换。

alt 客户端转换。

前面介绍的直接使用浏览器进行转换的方式是由浏览器实时转换,这种转换方式要求浏览器必须支持XML+XSLT。目前的各种主流浏览器,例如Internet Explorer 6.0及更高版本,Firefox 3.0及更高版本和Opera 9.5及更高版本,都对XML+XSLT有很好的支持。

由于XSLT 1.0标准是1999年底才发布,因此早期的浏览器对XML+XSLT的支持不够好,例如Internet Explorer 5.0、Internet Explorer 5.5等对XML+XSLT的支持就不太理想。

服务器端转换模式无须浏览器支持XML+XSLT,在这种模式下,服务器端通过各种编程语言将XML根据XSLT转换成HTML文档(实际上也可以输出成其他文档),然后将转换后得到的文档输出到客户端。

服务器端转换又可分为两种方式:

alt 实时转换:这种方式通常需要借助于JSP、PHP等动态脚本语言。当服务器接收到来自浏览器的浏览请求之后,JSP、PHP等脚本语言临时根据XSLT转换XML,然后将转换生成的HTML送回客户端。

alt 批量转换:这种方式适合于XML文档变化频率较低的情形,服务器端定期根据XSLT将XML转换成所需的HTML页面(实际上也可以输出成其他文档)。服务器接收到来自浏览器的浏览请求之后,直接将已有的HTML页面送给客户端即可。

目前Java领域有如下两个常用的XSLT转换项目,它们都能在服务器端对XML进行转换:

alt Xalan:Xalan是Apache软件基金组织的一个子项目,其官方站点是http://xalan.apache.org,读者可以登录该站点了解该项目的详细情况。Xalan目前有2个子项目:Xalan C++和Xalan Java,前者是C++领域的实现,后者是Java领域的实现。Xalan仅仅实现了XSLT 1.0和XPath 1.0。

alt Saxon:Saxon是SourceForge软件基金组织的一个子项目,其官方站点是http://saxon.source forge.net,读者可以登录该站点了解该项目的详细情况。Saxon有Java和.NET两个版本。相对于Xalan,Saxon完全实现了XSLT 2.0、XQuery 1.0和XPath 2.0等规范,因此功能更加强大。

8.3.2 Xalan处理器

Xalan处理器有两种用法,它既可以作为独立的应用程序对XML进行转换,也可以作为Web应用的类库在JSP页面里执行实时转换。

下载Xalan请按如下步骤进行:

(1)登录http://xml.apache.org/xalan-j/downloads.html站点下载Xalan-J的最新稳定版本。笔者成书之时,该项目的最新版本是Xalan-Java 2.7.1,建议读者也下载该版本的Xalan。

(2)Xalan有两个发布版本:

alt xalan-j_2_7_1-bin.zip或xalan-j_2_7_1-bin.tar.gz:它将Xalan交互处理器、Xalan编译后处理器(Xalan Compiled processor,即XSLTC)和运行所需的第三方类库放在一个单独的xalan.jar包里。读者使用这个发布版本显然更省事。

alt xalan-j_2_7_1-bin-2jars.zip或xalan-j_2_7_1-bin-2jars.tar.gz:它将Xalan交互处理器放在xalan.jar里,将Xalan编译后处理器和运行所需的第三方类库放在xsltc.jar里。使用这个发布版本会比较麻烦。

建议读者下载第一个发布版本,Windows平台下应下载xalan-j_2_7_1-bin.zip压缩包。

(3)解压缩前面下载的xalan-j_2_7_1-bin.zip文件,可看到如下文件结构:

alt docs:该目录下存放了Xalan的各种帮助文档,包括API文档等。

alt samples:该目录下存放了Xalan的各种用法示例,这些示例对初学者学习Xalan的用法有很大的帮助。

alt xalan.jar:这就是Xalan的核心类库,它包含了Xalan交互处理器、Xalan编译后处理器和运行所需的第三方类库。运行它通常要依赖于serializer.jar文件。

alt xercesImpl.jar、xml-apis.jar:这是JAXP(Java API for XML Processing)的两个核心类库。

alt 其他文件:包括LICENSE.txt、NOTICE.txt等说明性文档。

xalan.jar本身就是一个可执行的程序,因此完全可以在命令行窗口中运行,由于xalan.jar还依赖于serializer.jar文件,因此应使用如下命令来运行:

alt


alt提示

上面的用法与Xalan无关,而仅仅是java命令的用法,-classpath选项用于指定临时的类加载路径,-jar选项用于指定该命令所运行的JAR包。关于java命令的详细用法请参阅疯狂Java体系的《疯狂Java讲义》。


执行上面的命令,可看到图8.10所示窗口。

alt

图8.10 执行xalan.jar

如图8.10所示,执行xalan.jar时可以指定许多选项,读者可以通过阅读上面的说明来了解各选项的用法。实际应用中下面3个选项比较常用:

alt -IN:指定需要转换的XML文档。

alt -XSL:指定进行转换的XSLT样式单文档。

alt -OUT:指定转换后输出的目标文档。

如果在XML文档中已经引入了XSLT文档,则执行xalan.jar时可以省略-XSL选项,例如执行如下命令:

alt

上面的命令会把当前目录下的book.xml文档转换成a.html页面,读者可以在codes\08\8.3\xalan目录下找到一个transform.cmd文件(该文件的内容就是上面的命令),双击该文件将可以看到该目录(该目录下已有book.xml和book.xslt文档)下多出一个a.html页面,它就是由book.xml文档转换得到的。


alt提示

从这里可以清楚地看出:XSLT对XML执行转换时会额外生成一个新文档,这与CSS的处理方式截然不同。即使使用浏览器执行客户端转换时,浏览器也会额外生成一份新文档,只不过它没有直接输出到用户磁盘。


此外,我们完全可以在Web应用中使用Xalan进行实时转换。使用Xalan进行实时转换主要依赖如下几个类和接口:

alt TransformerFactory:转换器工厂,它负责生成转换器。

alt Transformer:XSLT转换器,它负责加载XSLT样式单文档,并执行实际转换。

alt Source:代表源XML文档的接口。

alt Result:代表转换结果文档的接口。

因为Source和Result两个都是接口,所以实际应用中必须使用其实现类,它们有图8.11所示的常用实现类。

alt

图8.11 Source和Result

Source总是代表需要被转换的源XML文档,图中的DOMSource、StreamSource和SAXSource只是源XML文档的几种不同存在形式而已,其中StreamSource代表磁盘上的IO流中的XML文档。关于DOM、SAX的介绍请参考本书第10章的内容。类似地,DOMResult、StreamResult和SAXResult都代表转换得到的目标文档,只是存在形式不同而已,其中StreamResult代表磁盘上的IO流中的目标文档。

使用Xalan在程序中进行转换的步骤如下:

(1)使用TransformerFactory的newInstance()方法创建一个转换器工厂。

(2)调用转换器工厂的newTransformer(Source src)方法创建一个转换器,此处的src代表一个XSLT样式单文档。

(3)调用转换器的transform(Source src, Result result)方法执行转换。其中src代表需要被转换的XML文档,而result代表转换得到的结果文档。

例如如下JSP页面就可以执行实时转换:

程序清单:codes\08\8.3\xalanQs\test.jsp

alt

上面的JSP页面以WEB-INF/下的book.xslt样式单对WEB-INF/下的book.xml文档进行实时转换,通过浏览器请求该页面,可看到图8.12所示结果。

alt

图8.12 使用Xalan进行实时转换

8.3.3 Saxon处理器

Saxon是Michael Kay开发的XSLT处理器,它完全实现了XSLT 2.0、XQuery 1.0和XPath 2.0等规范。Saxon有两个版本:Saxon-SA和Saxon-B,其中Saxon-SA是商业版,而Saxon-B则是免费的开源版。据Saxon官方称:Saxon-SA更稳定,而且还有一些附加功能,读者可自行登录其官方站点查看。

本书所介绍的Saxon是开源、免费的Saxon-B版,下载Saxon-B版请按如下步骤进行:

(1)登录http://saxon.sourceforge.net/站点下载Saxon-B的最新稳定版本。笔者成书之时,该项目的最新版本是Saxon-B 9.1.0.6,建议读者也下载该版本的Saxon。

(2)下载完成后,解压缩下载到的saxonb9-1-0-6j.zip文件,可看到如下文件结构:

alt doc:该目录下存放了一份简单的帮助文档,其中只有到实际参考文档和API文档的链接,并不是真正的文档。

alt notices:该目录下存放了各种注意文档,通常无须理会。

alt saxon9.jar和多个saxon9-xxx.jar文件:其中的saxon9.jar就是我们要使用的核心JAR包。


alt提示

如果不希望每次查看Saxon的文档都要连接互联网,也可以下载其离线文档,Saxon的下载列表页面里有一个“Download documentation and samples”链接,单击该链接就可以下载其文档和用法示例。


就用法来看,Saxon和Xalan的差别并不大:都既可以作为独立的应用程序来运行,转换指定的XML文档,也可以放在Web应用中运行,而且用法也接近。

在命令行窗口中输入如下命令:

alt

执行上面的命令可看到图8.13所示显示。

alt

图8.13 执行saxon.jar

如图8.13所示,执行saxon.jar时可以指定许多选项,读者可以通过阅读上面的说明,或者参考http://www.saxonica.com/documentation/using-xsl/commandline.html文档,来了解各选项的功能和用法。

实际应用中下面3个选项比较常用:

alt -s:指定需要转换的XML文档。

alt -xsl:指定进行转换的XSLT样式单文档。

alt -o:指定转换后输出的目标文档。

与Xalan不同的是,在使用Saxon进行转换时,即使XML文档中已经引入了XSLT文档,也依然需要指定-xsl选项,例如执行如下命令:

alt

上面的命令会把当前目录下的book.xml文档转换成a.html页面,读者可以在codes\08\8.3\saxon目录下找到一个transform.cmd文件(该文件的内容就是上面的命令),双击该文件将可以看到该目录(该目录下已有book.xml和book.xslt文档)下多出一个a.html页面,它就是由book.xml文档转换得到的。

类似地,也可以在Web应用中使用Saxon,只要将saxon9.jar复制到Web应用的WEB-INF/lib路径下即可。JSP页面同样使用如下代码即可进行实时转换:

程序清单:codes\08\8.3\saxonQs\test.jsp

alt

通过浏览器请求该JSP页面,即可看到实时转换XML的结果。


alt学生提问:我发现用Saxon进行实时转换和用Xalan进行实时转换的JSP页面代码完全相同,这是为什么呢?


答:这是因为不管是Xalan,还是Saxon,都只是XSLT的一种实现方式,而上面的JSP页面中所用的TransformerFactory、Transformer、Source和Result,既不属于Xalan,也不属于Saxon,而是属于JAXP规范的。这意味着程序面向的是JAXP通用规范,至于底层到底是采用Xalan实现,还是采用Saxon实现,对程序员而言是完全透明的。这和使用JDBC编程的道理是一样的,应用程序面向通用的JDBC规范编程,至于底层使用哪种JDBC驱动,对开发者而言也是透明的(除了需要显式加载数据驱动外)。

实际上,使用Xalan进行实时转换和使用Saxon进行实时转换是有区别的,关键在于Transformer Factory的newInstance()方法,这个方法可根据系统的javax.xml.transform.TransformerFactory属性来选择转换器工厂类。如果系统没有指定该属性,则由TransformerFactory自行“智能”选择——它只是选择类加载路径中可以找到的TransformerFactory子类。

实际上程序员也可以强制指定使用哪种转换器工厂类,如果希望程序使用Xalan的转换器工厂类,可以调用如下代码来设置系统属性:

alt

如果希望程序使用Saxon的转换器工厂类,可以调用如下代码来设置系统属性:

alt

使用上面的两行代码,既可以强制程序使用哪种转换工厂类,又具有较好的可读性:一眼就可以看出底层使用的是哪种XSLT转换器实现。但有一个很大的劣势:当底层需要在不同的XSLT转换器实现之间切换时,必须手动修改程序代码。

alt