使用Xalan进行XSLT程序设计
--基本概念
下面我们介绍使用Xalan进行程序设计所需要基本概念。
Xalan建议在进行XSLT程序设计的时候应该使用TRaX提供的接口。TRaX是java社区提供的进行XML transformation的标准,在javax.xml.transform包中。
在了解javax.xml.transform包之前,我们需要先了解以下术语。这些术语将在我们的介绍中大量使用。
Source
表示输入,这个输入可以是一个普通的xml文件,一个xsl文档,一字节流等等。
Result
表示处理的结果。
Templates模板集
表示xsl文档中的所有模板的集合。在Templates中仅仅储存xsl文档中的处理指令,Templates不进行实际的处理工作。
Transformer
表示进行transform实际处理工作的java类的实例。
在javax.xml.transform包中定义了如下的界面和类。
其中TransformerFactory是我们进行程序设计的起点,这个类是一个抽象类,因此不能直接实例化,通过这个类中的newInstance方法,我们可以获取一个TransformerFactory类的实例。这个类中的重要方法如表1:
方法名 | 使用说明 |
Source getAssociatedStylesheet(Source source, java.lang.String
media, |
这个方法返回一个XML文件中通过处理指令(process instruction)指定的XSL文件。第一个参数是XML文件的输入Source,关于Source我们会在后面介绍。第二个参数为MIMETYPE,可以为null,例如一个xml文件可以指定text/xsl和text/xml两种不同的xsl处理方法,其中一个用于前台(ie5)使用,另一个在后台由Xalan使用。第三个参数为指定的title,也可以为null,实话实说,cyfer从来没有在这个地方使用过title。的四个参数为指定的字符集,也可以为null。显然通过选择不同的字符集我们可以为不同的客户端提供不同的内容。 |
java.lang.Object getAttribute(java.lang.String name) | 获取指定属性的值。 |
ErrorListener getErrorListener() | 获取ErrorListner。 |
boolean getFeature(java.lang.String name) | 获取指定的Feature是否支持。 |
URIResolver getURIResolver() | 获取URIResolver。 |
TransformerFactory newInstance() | 重要的方法,返回一个TransformerFactory地实例。 |
Templates newTemplates(Source source) | 重要方法,从一个XSL文件生成一个Template。在多线程程序设计,例如Servlet和JSP中,这是最重要的处理方式。参数为XSL文件的Source。 |
Transformer newTransformer() | 重要方法,生成一个Transformer。整个Transformer的功能就是,不作任何处理,直接把输入复制到输出中去。 |
Transformer newTransformer(Source source) | 重要方法,从一个Source生成一个Transformer。整个方法在单线程程序设计中经常使用。 |
void setAttribute(java.lang.String name, java.lang.Object value) | 设置一个Attribute。 |
void setErrorListener(ErrorListener listener) | 设置一个ErrorListener。 |
void setURIResolver(URIResolver resolver) | 设置一个URIResolver。 |
Templates(注意是复数)是另一个很重要的概念。从某种意义上来讲,Templates代表了一个StyleSheet文件编译后的结果,但是Templates不进行实际的转换工作而仅仅储存所有的转换指令。Templates对象是多线程安全的,多个线程可以同时访问同一个Templates对象。Templates界面中只有两个方法。如表2。
方法名 | 使用说明 |
java.util.Properties getOutputProperties() | 获取和xsl:output相关的信息。 |
Transformer newTransformer() | 获取一个新的Transformer。在多线程程序设计中应该使用这个方法来获取Transformer。 |
Transformer是执行实际的转换工作的对象。Transformer界面中的方法大多于TransformerFactory中的相同,我们在这里介绍四个特别的方法。如表3。
方法名 | 使用说明 |
void transform(Source xmlSource, Result outputTarget) | 这个方法执行实际的转换工作。第一个参数为一个输入的Source第二个参数是输出的结果。 |
void setParameter(java.lang.String name, java.lang.Object value) | 设置一个处理中使用的参数,使用方法与setAttribute相同。但是需要注意的是第一个名字使用的格式为QName方式,即{http://a.b.c/d/e.html}fghi |
Object getParameter(java.lang.String name) | 获取一个参数。 |
void clearParameters() | 清除所有的参数。 |
Source界面定义了用来输入所需的方法,有DOMSource,SAXSource和StreamSource三个实现。Result界面定义了用来输出所需的方法,同样有DOMResult,SAXResult和StreamResult三种。Source和Result界面并没有定义与进行XSLT直接相关的方法,而且两个界面中定义的方法都是相同的,其中定义的方法如下表。
方法名 | 使用说明 |
getSystemId() | 获取输入源或者输出目的的系统代号。 |
setSystemId(java.lang.String systemId) |
摄制输入源或者输出目的的系统代号。 |
DOMSource位于javax.xml.transform.dom包中,用来从一个Node中接收信息。其结构方法和成员方法如表4。
方法名 | 使用说明 |
DOMSource() | 缺省的结构方法。 |
DOMSource(Node n) | 以参数为输入源创建一个DOMSource。 |
DOMSource(Node node, java.lang.String systemID) | 第一个参数为输入节点,第二个参数为一个SystemID。 |
Node getNode() | 获取作为输入源的根节点。 |
String getSystemId() | 获取SystemID。 |
void setNode(Node node) | 设置输入源节点。 |
void setSystemId(java.lang.String baseID) | 设置SystemID。 |
SAXSource位于javax.xml.transform.sax包中,可以和一个XMLReader或者InputSource合作,以SAX方式完成输入。
方法名 | 使用说明 |
SAXSource() | 缺省的结构方法。 |
SAXSource(InputSource inputSource) | 在一个InputSource的基础上创建一个SAXSource |
SAXSource(XMLReader reader, InputSource inputSource) | 在一个XMLReader的基础和一个InputSource的基础上创建一个SAXSource,这里SAXSource会把自己设置成XMLReader的Handler然后调用reader.parse( inputSource )进行解析。 |
void setInputSource(InputSource inputSource) | 设置InputSource |
void setSystemId(java.lang.String systemId) | 设置系统代号。 |
void setXMLReader(XMLReader reader) | 设置XMLReader。 |
static InputSource sourceToInputSource(Source source) | 从一个Source对象获取一个InputSource。参数不可以为null。 |
StreamSource位于javax.xml.transform.stream可以从一个流内读取信息,完成输入。
方法名 | 使用说明 |
StreamSource() |
缺省的结构方法。 |
StreamSource(java.io.File f) | 从一个文件创建一个StreamSource。 |
StreamSource(java.io.InputStream inputStream) | 从一个InputStream创建一个StreamSource。 |
StreamSource(java.io.InputStream inputStream, java.lang.String systemId) | 从一个InputStream创建一个StreamSource,并赋予一个系统代号。 |
StreamSource(java.io.Reader reader) | 从一个reader创建一个StreamSource。 |
StreamSource(java.io.Reader reader, java.lang.String systemId) | 从一个reader创建一个StreamSource,并赋予一个系统代号。 |
StreamSource(java.lang.String systemId) |
从一个URL创建一个StreamSource。 |
java.io.InputStream getInputStream() | 从一个StreamSource对象中获取InputStream。 |
java.lang.String getPublicId() | 从一个StreamSource对象中获取其系统代号。 |
java.io.Reader getReader() |
从一个StreamSource对象中获取reader。 |
java.lang.String getSystemId() | 获取这个StreamSource对象的系统代号。 |
void setInputStream(java.io.InputStream inputStream) | 设置StreamSource对象中的InputStream。从这个InputStream中读取信息。 |
void setPublicId(java.lang.String publicId) |
设置StreamSource对象的公共代号。可选。 |
void setReader(java.io.Reader reader) |
设置StreamSource对象的reader。从这个reader中读取信息。 |
void setSystemId(java.io.File f) | 用一个文件的引用设置系统代号。 |
void setSystemId(java.lang.String systemId) |
设置系统代号。 |
DOMResult位于javax.xml.transform.dom包中,用来容纳DOM形式的输出结果。
方法名 | 使用说明 |
DOMResult() | 缺省的结构方法。 |
DOMResult(Node node) | 创建一个新的实例,并且使用参数中给出的Node来容纳输出的结果,因此,这个Node应该是一个能够容纳子节点的Node,或者说,是一个Element,Document或者DocumentFragment。 |
DOMResult(Node node, java.lang.String systemID) | 同上,但是给Node一个系统id。 |
Node getNode() | 获得容纳输出结果的Node的引用。 |
java.lang.String getSystemId() |
获取系统id。 |
void setNode(Node node) | 设置用来容纳输出结果的Node。 |
void setSystemId(java.lang.String systemId) | 设置系统id。 |
SAXResult位于javax.xml.transform.sax包中,用来容纳SAX形式的输入结果。SAXResult需要同一个ContentHandler一起使用。
方法名 | 使用说明 |
SAXResult() | 缺省的结构方法。 |
SAXResult(ContentHandler handler) | 创建一个实例并且设置一个ContentHandler用来处理输出的结果。 |
ContentHandler getHandler() | 获取ContentHandler。 |
LexicalHandler getLexicalHandler() | 获取LexicalHandler。 |
java.lang.String getSystemId() | 获取系统id。 |
void setHandler(ContentHandler handler) |
设置ContentHandler。 |
void setLexicalHandler(LexicalHandler handler) | 设置LexicalHandler,LexicalHandler能够报告整个文件的结构,即根结点以外的内容一样可以处理。 |
void setSystemId(java.lang.String systemId) | 设置系统id。 |
StreamResult位于javax.xml.transform.stream包中,用来直接把输出的结果输出到一个流或者一个writer中。
方法名 | 使用说明 |
StreamResult() | 缺省的结构方法。 |
StreamResult(java.io.File f) | 创建一个实例,并把结果输出到参数所指明的文件中。 |
StreamResult(java.io.OutputStream outputStream) |
创建一个实例,并把结果输出的参数所指明的二进制流中。 |
StreamResult(java.lang.String systemId) | 创建一个实例,并把结果输出到参数所指明的系统id(url)所相关的文件或者其他任何对象中。 |
StreamResult(java.io.Writer writer) | 创建一个实例并把结果输出到参数所指明的writer中。同使用OutputStream的方法相比,这种方法由于writer会使用系统的encoding所以无法处理非系统制定的encoding。因此不如使用OutputStream的方法好。 |
java.io.OutputStream getOutputStream() | 返回OutputStream。 |
java.lang.String getSystemId() |
获取系统id。 |
java.io.Writer getWriter() | 获取所使用的writer。 |
void setOutputStream(java.io.OutputStream outputStream) | 设置OutputStream。 |
void setSystemId(java.io.File f) | 获取一个文件的系统id并使用这个系统id。 |
void setSystemId(java.lang.String systemId) |
设置系统id。 |
void setWriter(java.io.Writer writer) | 设置writer。 |