当前位置:编程学习 > JSP >>

使用Java与XSLT的10条技巧

答案:在我的新书《Java and XSLT》中介绍了Java与XSLT的技术组合。这篇文章从书中选出了我认为非常重要的10条技巧。但实际上这有限的10条只是粗略的描述了什么是可能的。其中大多数都集中在Java与XSLT的组合上,而不是在XSLT(可扩展样式表转换)技术规范。而更详细的信息,在文章结尾处指出了一些有价值的资源。
基本的XSL转换是非常简单的:一个或多个包含着指令的XSLT样式表,这些指令定义了如何把XML数据转换成其他格式。XSLT处理器完成实际的工作;Sun微系统的Java API for XML Processing (JAXP)为不同种类的处理器提供了一套标准的Java接口。这里有一个用JAXP的API执行XSL转换的简单例子:
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
public class Transform {
/**
* Performs an XSLT transformation, sending the results
* to System.out.
*/
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.err.println("Usage: java Transform [xmlfile] [xsltfile]");
System.exit(1);
}
File xmlFile = new File(args[0]);
File xsltFile = new File(args[1]); // JAXP reads data using the Source interface
Source xmlSource = new StreamSource(xmlFile);
Source xsltSource = new StreamSource(xsltFile);
// the factory pattern supports different XSLT processors
TransformerFactory transFact = TransformerFactory.newInstance();
Transformer trans = transFact.newTransformer(xsltSource);
trans.transform(xmlSource, new StreamResult(System.out));
}
}
你可以点击这里下载一个很小的ZIP文件,这个文件包含了这个例子以及相应的XSLT样式表和XML数据文件。其中的README文件解释了怎样编译和运行这个例子。
这个这个例子是利用StreamSource从文件中读取数据,JAXP还能从SAX解释器或DOM树来读取XML数据。下面依次介绍我推荐的10条技巧:

1、 尽可能使用缓存。
执行XSLT转换是很耗费CPU和内存的,所以在任何时候进行可能的优化都是很有意义的。使用由XSLT驱动的Web应用,提高它的实时运行性能表现的最好方法之一就是使用各种类型的缓存技术。
图一举例说明了一个典型的使用XSL对数据库进行转换的Web应用。



图一、典型的XSL转换

与动态生成的XML不同,XSLT样式表是静态存储在文件中的。由于这些文件很少被改动,就可以用JAXP的javax.xml.transform.Templates接口把它们解析好了进内存里缓存起来。下面这个程序片断解释了这个过程是怎样完成的:
Source xsltSource = new StreamSource(xsltFile);
TransformerFactory transFact = TransformerFactory.newInstance();
Templates cachedXSLT = transFact.newTemplates(xsltSource);
Transformer trans = cachedXSLT.newTransformer();
当XSLT样式表通过Templates接口缓存进了内存中,现在它就可以被重复用于很多不同的转换里。最重要的好处是,这样就避免了重复把XSLT解析进内存。它也给了XSLT处理器一个机会来优化转换指令,就象编译器优化软件那样。
有人可能会想是否可以把XML数据也缓存进内存中。对于那些高度动态和个体化的应用,XML数据是随着每一个客户请求而动态生成的并随时都在变化。对于这种应用,缓存是不实际的。对于很多其它类型的应用,XML数据可能改变的不是很频繁。当数据改变不是很频繁时,相对于缓存XML数据,将转换后的结果缓存可能更有意义。这是一种最快的可行性解决方案,推荐在任何可行的情况下使用。

2、部署前做测试。
在开发Web应用项目选择XML和XSLT的关键在于可以清楚的把数据、程序逻辑和表达分开。Java代码与后台数据源交互并生成XML数据,XSLT样式表把XML数据转换为XHTML(或WML,或其它),然后浏览器显示结果。
这种结构的一个独特的,然而时常被忽略的好处是它支持自动单元测试的能力。象JUnit这样的工具鼓励程序员去写适合自动单元测试的套件。这些测试大大的减少了在系统中加入新特性时所产生的错误。考虑一下一个典型的Java+XML+XSLT网站的这些组件:
用Java实现商业逻辑。由于Java代码没有和表达逻辑混在一起,就可以象其他任何Java代码一样测试它。
把应用数据转换为XML。这一步是特别容易的。只要生成XML然后用一个DTD或一个XML Schema验证它就行了。
把XML转换为XHTML。同样的,生成的XHTML可以用一个XHTML DTD来验证。虽然这样做不能证明信息是正确的,但是的确能保证XHTML被正确的生成而且是有效的。
与很多其它的Web开发技术不同,测试这些单元中的任何一个都不用将其部署到Web服务器上。这使自动单元测试更容易被实现,自动单元测试也是极限编程(XP)技术的一个关键组成部分。

3、尽量让XSLT样式表简单。
至少有两个理由要保持XSLT样式表简单。第一,XSLT并不是一个象Java那样丰富的编程语言。虽然XSLT擅于转换,但是在样式表中嵌入太多的应用逻辑会使它变得相当复杂。因为这个原因,就应该在创建XML之前用Java实现尽可能多的商业逻辑。然后再用XSLT转换XML就应该简单得多了。
第二个保持样式表简单的理由是XSLT的语法不容易被读懂。XML标签使XSLT很容易解析和方便的做程序化的处理,但所有的那些XML标签也使得样式表不容易被读懂。有几个小技巧可以帮助程序员更容易读懂和处理XSLT样式表:
使用具有语法区分功能的编辑器,如Altova的XML Spy。
为每一个XSLT模板添加有区别的注释。这样就有助于打破那种在大堆被括在'<'和'>'的字符串里搜索时的单调。
对最高层的变量和样式表参数采用一定的命名规则。
把通用的方法取出来放进第二个样式表中,用<xsl:import>来重用代码。
4、和XSLT一起使用CSS。
这条技巧是和上一条联系在一起的,它也可以大大的减少XSLT样式表的复杂程度。
XSLT和CSS分别执行不同的任务并相互补充。XSLT把XML转换为其他的格式,如XHTML或WML,而CSS只是定义表达的样式。作为生成的XHTML的一部分,有时XSLT也可以生成一些样式元素来使线条变模糊。
建议写一些独立的CSS文件,来代替在XSLT样式表中嵌入大量关于字体、颜色和其它的样式元素。XSL转换产生的XHTML只是包含这些独立的CSS文件。这就使XHTML更小,同时简化了XSLT,也使得浏览器下载页面时速度更快。
同样的技术也适用于javascript,应该存放一些独立的文件而不是把它们直接嵌入到转换中去。

5、小心处理不间断空格。
作者提示:作为对读者的回应,我已经重写了这条技巧,加入了我最近学到的关于不间断空格的新知识。感谢广大读者的反馈。[编者提示:我们已经在文件的尾部为附加评论加入了一个读者反馈链接。]
不间断空格对于XHTML来说是一个很有用的特性,它可以阻止浏览器在文字中引入换行符。它同时使得强迫两个以上连续的空格成为可能;因为浏览器总是把普通的空格(和其他的白空格字符)序列处理成一个空格。这里是一个包含不间断空格的XHTML的例子:
Aidan&nbsp;Burke
当人们创建XHTML网页时,他们通常是象上面显示的那样在他们的源文件中插入"&nbsp;"字符。所有的浏览器都会把这个字符序列翻译成一个不间断空格并正确显示。然而,当用XSLT生成XHTML时,处理的方法就不同了。
XSLT样式表必须是格式正确的XML。因为"&nbsp;"不是XML预先定义好的五个标签,它不能直接被包含在样式表中。比如,接下来的这个XSLT片就不管用:
<!-- won't work... -->
<xsl:text>Aidan&nbsp;Burke</xsl:text>
这种特征使XSLT程序员必须用一种略微不同的方法来使用这种特性:
<xsl:text>Aidan&#160;Burke</xsl:text>
结果表明,所有的案例都工作得很好。当样式表的输出方法是"html"时,像Xalan这样的处理器会自动的把字符实体"&#160;"转换为序列"&nbsp;"。从网络浏览器的角度来看,这看起来和其它的不间断空格没什么两样。
这里有一个完整的XSLT样式表的例子就是这样做的
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:text>Aidan&#160;Burke</xsl:text>
</xsl:template>
</xsl:stylesheet>
当用Xalan时,这个转换的输出看起来是这样的:
Aidan&nbsp;Burke
这很好,因为浏览器知道如何显示"&nbsp;"。但很不幸,XSLT规范并没有要求XSLT处理器把"&#160;"转换为"&nbsp;"。你必须在遇到这个问题的任何时候,对你使用的XSLT处理器进行这项测试。
有些程序员不喜欢必须记住"160"代表不间断空格。所以他们在XSLT样式表的DTD子集中定义这样一个实体:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp "&#160;">
]>
<xsl:stylesheet version="1.0&q

上一个:Java的文件 读和写
下一个:Java常见问题总结

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,