|
技巧:使用SAXTransformerFactory--利用XSLT实现更好的灵活性和方便广告 技巧:使用SAXTransformerFactory
在这篇详细的技巧说明中,Benoit Marchal 说明了当保存 XML 文件时,SAXTransformerFactory
— 直接在 XSLT 处理器中提供 SAX 事件的类 — 如何带给您更好的灵活性。几段可重用 Java 代码样本演示了该技术,这些代码样本需要使用
TrAX。 我过去常常使用单独的应用程序来后处理文件,但用户逐渐要求使用一个集成的解决方案来模拟他们熟悉的商业生产应用程序中的“导出...”或“另存为...”菜单命令。 在搜寻好的解决方案的过程中,我最终找到了 SAXTransformerFactory。对于本讨论的其余部分,我假设您已经了解 SAX 语法分析、TrAX(XSLT 处理器的标准 Java API)和 XSLT。如果需要了解一些背景知识,请参阅参考资料以获取参照。 SAX 和 XSLT 处理器 您也许会问,为什么要那么麻烦?毕竟,TrAX 还支持 SAXSource 以便与 SAX 语法分析器结合。的确,如果使用成熟的 SAX 语法分析器,SAXTransformerFactory 就没什么用处了。但我发现,在没有语法分析器的情况下,从我的应用程序生成那些事件还是合算的。 请考虑图 1。其中发生了两件事:首先应用程序将数据写入 XML 文件,然后 XSLT 处理器(另一个应用程序)将数据整理成 HTML 格式。 图 1. 典型的 XML 和 XSLT 应用程序
的确,在第一种情况中,应用程序编写了 XSLT 处理器可以立即分析的 XML 文档(通常通过 SAX 语法分析器)。如图 2 所示,如果应用程序发出 SAX 事件本身,是否会更有效呢?在图 2 中,应用程序并没有写到文件中,而是直接调用处理器的 ContentHandler,有效地模拟了语法分析器。 第二种模式更有效,它使用较少的内存,并省去了创建和删除临时文件的烦恼。 图 2. 应用程序模拟语法分析器
asXML() 方法将 Properties 对象写成 XML 格式,但它没有写到文件中;而是使用 ContentHandler。 如果没有名称空间,代码会很简单。经验显示发出 startPrefixMapping() 并将 xmlns 声明当作常规属性传送会更安全。 清单 1. asXML() 模拟 SAX 语法分析器 protected static void asXML(Properties properties,ContentHandler contentHandler) throws SAXException { AttributesImpl attributes = new AttributesImpl(); contentHandler.startDocument(); contentHandler.startPrefixMapping("ps", "http://www.psol.com/2001/08/dw/tip"); attributes.addAttribute("","ps","xmlns:ps","CDATA", "http://www.psol.com/2001/08/dw/tip"); contentHandler.startElement("http://www.psol.com/2001/08/dw/tip", "properties","ps:properties",attributes); attributes.clear(); Enumeration enumeration = properties.propertyNames(); while(enumeration.hasMoreElements()) { String name = (String)enumeration.nextElement(), value = properties.getProperty(name); contentHandler.startElement("http://www.psol.com/2001/08/dw/tip", "property","ps:property",new AttributesImpl()); contentHandler.startElement("http://www.psol.com/2001/08/dw/tip", "key","ps:key",attributes); contentHandler.characters(name.toCharArray(),0,name.length()); contentHandler.endElement("http://www.psol.com/2001/08/dw/tip", "key","ps:key"); contentHandler.startElement("http://www.psol.com/2001/08/dw/tip", "value","ps:value",attributes); contentHandler.characters(value.toCharArray(),0,value.length()); contentHandler.endElement("http://www.psol.com/2001/08/dw/tip", "value","ps:value"); contentHandler.endElement("http://www.psol.com/2001/08/dw/tip", "property","ps:property"); } contentHandler.endElement("http://www.psol.com/2001/08/dw/tip", "properties","ps:properties"); contentHandler.endPrefixMapping("ps"); contentHandler.endDocument(); } 调用 XSLT 处理器 最后,使用 newTransformerHandler() 来请求 TransformerHandler 对象。该方法使用样式表的 URI 作为参数。TransformerHandler 实现了 ContentHandler,并且可以作为参数传递给 asXML()。 如果熟悉 TrAX,您也许想要知道在哪里调用 transform()。答案是不必这样做。TransformerHandler 在接受 SAX 事件时会应用样式表。 HTML 样式表 Key Value 高性能的序列化程序 SAXTransformerFactory 的其它应用程序 Xalan
是支持 SAX,功能强大的 API,这是从作者著作 XML by Example 第二版中摘录的一章,Que Publishing 将在 2001 年 9 月发行该书,该书详细地讨论了 SAX。 Brett McLaughlin 撰写的 Sun's Java API for XML Parsing, Version 1.1,此文介绍了结合了 SAX、TrAX 和 DOM 的 JAXP 1.1。请转向 Sun 公司的官方网页 Java Technology and XML。 David Mertz 撰写的使用 XSLT 转换 DocBook 文档是学习 XSLT 的一个好的起点。 Michael Kay 撰写的 Saxon: 剖析 XSLT 处理器是关于 XSLT 处理器最有趣的讨论。 IBM FAQs 回答了关于 XML 和 IBM 产品的常见问题。 The XML certification guidelines 提供了掌握在 IBM
Certified Developer Program 中进行 XML 开发需要的详细技术。 如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐 jill.jiang@amt.com.cn | 021-51096826-112 | 在线联系 |
CIO职场,强者生存?在2008年,我们将继续看到CIO向商业运营方向发展。与此同时,我们也会看到商业管理人员将与技术管理人员一起竞争CIO岗位。 IT领导者的就职机会虽有不少,但其难度将会大幅提高。2…… |
|
|