存储数据,比如,存储为 XForms/REST/XQuery [XRX] 架构的一部分(参见 参考资料)在如今很常见。您可以查询、检索以这种方式存储的数据并将其序列化为想要的格式。对于 Web 应用程序,开发人员可能希望允许用户以 HTML 格式(以便在其 Web 浏览器中查看)或以 PDF 文件的形式(以便下载供以后使用)检索数据。
本文介绍如何借助一个基于 CSSToXSLFO 工具的 XQuery 扩展函数,将 XML 数据转换为 HTML,从该 HTML 转换为 XSL-FO,以及从 XSL-FO 转换为 PDF(参见 参考资料)。
通常,您需要两个 XSL 样式表来将数据从 XML 转换为 HTML 和 XSL-FO:一个将 XML 转换为 HTML,另一个 XSL-FO 样式表将 HTML 转换为 XSL-FO 文档,然后可以使用 XSL-FO 处理器将该文档转换为 PDF。这个过程表明,在以 HTML 和 PDF 格式生成报告的 Web 应用程序等环境中,您必须编写一个新 XSLT 样式表来将数据转换为 HTML,然后编写、调试和维护相应的 XSL-FO 样式表。这些样式表可能很难掌握,而且 XSL-FO 也不那么容易使用。幸运的是,因为报告不需要很复杂,所以您可以在 CSS 文件中轻松表达布局。然后,可以使用 CSSToXSLFO 实用工具进一步处理 CSS 文件,该实用工具只需少量编码即可生成 XSL-FO 文档。
这个过程和其他类似场景是本文所提供方法的完美用例,即,编写一个将 XML 转换为 HTML 的 XSLT 样式表,然后再向其添加些额外的 CSS 指令,以便它可将 HTML 转换为 XSL-FO,然后再转换为 PDF。
CSSToXSLFO 实用工具允许将 XML 文档连同一个 CSS version 2 (CSS2) 样式表转换为 XSL-FO 文档。为了使用此实用工具,我为 eXist XML 数据库开发了一个 XQuery 扩展函数,作为 XQuery 扩展模块中用于数字发布的一部分。
此实用工具可处理大部分 CSS2 规范。为了处理特定的 XSL-FO 功能,它提供了通常被浏览器忽略的多个 CSS 扩展指令。可在 CSS 样式表的 @media 打印部分的 @page 规则中使用这些属性。这些属性与页面区域、页码、引用、引导符、命名字符串、连字符、脚注、外部图形和外部元素相关。一定要查看 CSSToXSLFO 实用工具的收藏(参见 参考资料),了解该工具的更多信息和完善您设计的 XSLT 样式表的技巧。
eXist-db 是一个开源的数据库管理系统,完全使用 XML 技术构建。除了其他标准,它还支持 XQuery、XPath 和 XSLT。eXist 依据 XML 数据模型来存储数据,高度遵守 XQuery 标准。存储的数据使用 XQuery 通过基于索引的方式来处理。该数据库还有一个基于 Apache Lucene 的全文索引。
eXist 的 XQuery 引擎是可扩展的,所以 eXist 拥有各种各样的 XQuery 扩展模块。这些模块提供了 XQuery 扩展功能,比如:
- 全局键-值缓存
- 各种压缩操作
- 对日期和时间类型的更多操作
- 对文件和目录的各种操作
- HTTP 请求(一个 XPath 模块)
- 对存储在数据库中的图像的操作,包括检索图像维度,创建缩略图和调整图像大小
- 访问和操作基于 Java™ 命名和目录接口的目录,比如 LDAP
- 发送文本或 HTML 电子邮件
- 计划作业和操作现有作业
- 对关系数据库管理系统执行 SQL 操作
- 确定 XML 节点之间的区别
- XSL-FO 呈现
- XProc 功能
- 加密操作
eXist 和 CSSToXSLFO 都使用 Java 语言编写。在编写本文时,eXist 允许您使用 Apache 格式对象处理器 (Apache Formatting Objects, FOP) 或 RenderHouse XEP 作为 XSL-FO 处理器。请访问 eXist 网站,了解安装数据库的指令,以方便运行本文的示例。
eXist 数字发布模块目前正在开发中,在未来将包含更多函数。现在它拥有 html-to-xslfo() 函数,该函数有助于实现本文提供的方法。
此模块背后的意图是为数字发布所需的所有 XQuery 扩展函数提供单一的来源,包括各种格式之间的转换,比如 DocBook、Open XML、DOC、DOCX、.html、PDF、TXT、RTF、PPT、PPTX 和 CSV。要在 eXist 内安装此模块:
- 下载 eXist 数字发布模块的 JAR 文件,将其复制到 $EXIST_HOME/lib/extensions 中。
- 下载 css2xslfo1_6_2.jar,将其复制到 $EXIST_HOME/lib/user 中。
-
将
<module class="ro.kuberam.kPub.kPubModule" uri="http://kuberam.ro/k-Pub"/>添加到 $EXIST_HOME/conf.xml 文件的内置模块部分中。
本节分析 CSSToXSLFO 的用法,因为它是在 eXist 用于数字发布的 XQuery 扩展模块中实现的。对于此任务,使用 清单 1 中提供的 XML 数据,以及 下载 部分提供的代码示例中包含的 XSLT 样式表 (xml-to-html.xsl)。
备注:为了使本文更容易阅读,我没有包含所使用的 XSLT 样式表的完整内容。相反,我仅提供了那些使该样式表适合将 XML 转换为 HTML 和 PDF 的元素。
这些示例将上传到一个 eXist XML 数据库中,该数据库位于 eXist 根集合中的一个名为 html-and-pdf-single-stylesheet 的集合中,所以您可在浏览器中查看每个示例。例如,要查看示例 1,可在浏览器地址栏中键入以下地址(假设 eXist 安装在本地):
http://127.0.0.1:8080/rest/db/html-and-pdf-single-stylesheet/example%201/example1.xql |
要使用 CSSToXSLFO 工具中的更多功能,您只需要 清单 2 和 清单 3 中提供的 XQuery 代码,它们分别以 HTML 和 PDF 格式呈现代码。要获得更加完善的 PDF 文档,您必须向 XSLT 样式表的 CSS 部分添加 CSS 指令。
清单 1. 一个表示已开具发票的摘要的 XML 文档(示例代码中的文件 xml-data.xml)
<invoices-summary>
<invoice id="">
<issue-date>2011-10-17</issue-date>
<amount>108</amount>
<vat>19.47</vat>
<vat-base>22</vat-base>
<currency>EURO</currency>
<customer-id>0001008</customer-id>
</invoice>
<invoice id="">
<issue-date>2011-10-17</issue-date>
<amount>40</amount>
<vat>7.21</vat>
<vat-base>22</vat-base>
<currency>EURO</currency>
<customer-id>0000017</customer-id>
</invoice>
<invoice id="">
<issue-date>2011-10-17</issue-date>
<amount>1700</amount>
<vat>306.56</vat>
<vat-base>22</vat-base>
<currency>EURO</currency>
<customer-id>0000040</customer-id>
</invoice>
</invoices-summary>
|
第一个示例(如 清单 2 所示)是一段 XQuery 脚本,它将 清单 1 中给出的 XML 数据转换为 HTML。该脚本使用了 eXist 的 transform:transform() 函数,后者使用一个 XSLT 样式表和(可选的)转换参数来转换 XML 数据。您可以使用 XSLT 1.0(基于 Apache Xalan)或 XSLT 2.0(可选 Saxon)编写 XSLT 样式表。
清单 2. 将 XML 数据转换为 HTML 的 XQuery 脚本(示例代码中的文件 example-01.xql)
xquery version "1.0";
let $xml-data := doc('/db/html-and-pdf-single-stylesheet/xml-data.xml')
let $xslt-stylesheet := doc( '/db/html-and-pdf-single-stylesheet/xml-to-html.xsl' )
let $html := transform:transform($xml-data, $xslt-stylesheet, ())
return $html
|
图 1 显示了结果 HTML 文档在浏览器中的呈现效果。该 HTML 文档以一种非 serif 字体显示 3 个发票的细节摘要。(参见 图 1 和 2 中的格式化内容的文本版本。)
图 1. 转换为 HTML 的结果
首先,与在上一个示例中一样,将 XML 数据转换为了 HTML。结果 HTML 文档包含按要求呈现 HTML 文档所需的所有 CSS 指令,以及特定于 CSSToXSLFO 并有助于使用更复杂的 XSL-FO 功能的 CSS 扩展指令。
对于如本文中所示的简单用例,您不需要这些扩展指令。CSSToXSLFO 实用工具将 HTML 文档转换为一个 XSL-FO 文档,后者进而生成一个将非常类似于 HTML 文档的 PDF 文档。
接下来,您使用 html-to-xslfo() 函数将结果 HTML 文档转换为一个 XSL-FO 文档,然后生成一个 PDF 文档,如 清单 3 中所示。要创建 PDF,可使用 xslfo eXist 模块的 render() 函数。
清单 3. 将 XML 数据转换为 PDF 格式的 XQuery 脚本(示例代码中的文件 example-02.xql)
xquery version "1.0";
declare namespace xslfo="http://exist-db.org/xquery/xslfo";
declare namespace k-Pub="http://kuberam.ro/k-Pub";
let $xml-data := doc('/db/html-and-pdf-single-stylesheet/xml-data.xml')
let $xslt-stylesheet := doc('/db/html-and-pdf-single-stylesheet/xml-to-html.xsl')
let $html := transform:transform($xml-data, $xslt-stylesheet, ())
let $fo := k-Pub:html-to-xslfo($html)
let $pdf := xslfo:render($fo, "application/pdf", ())
return response:stream-binary( $pdf, "application/pdf", "output.pdf" )
|
图 2 显示了结果 PDF 文档在浏览器中的呈现效果。该 PDF 文档以一种 serif 格式显示 3 个发票的细节摘要。(请参见 图 1 和 2 中提供的格式化内容的文本版本。)
图 2. 转换成 PDF 格式的结果
清单 4 包含以 HTML 和 PDF 格式呈现 XML 所需的 CSS 指令。为了获得一个类似的 PDF 文件,我仅添加了一个 CSS 指令,将表标题加粗。
清单 4. 将 XML 呈现为具有类似外观的 HTML 和 PDF 的 CSS 指令
body {
font-family: arial;
font-size: 12px;
text-align: center;
}
table {
border-collapse: collapse;
width: 100%;
border: solid black 1px;
}
table th, td {
border: solid black 1px;
}
@media screen {
body {
width: 570px;
}
}
@media print {
table th {
font-weight: bold;
}
}
|
在本文中,您使用了一个简单函数来将 XML 数据转换为 HTML 和 PDF 格式,利用 CSS 语法和一些扩展指令的强大性和简单性来处理更加复杂的 XSL-FO 功能。在报告或文档样式较简单的情形中,这种方法特别有用。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| 完整代码示例 | html-and-pdf-single-stylesheet.zip | 4KB | HTTP |
学习
- 使用 XRX 进行 Web 开发:查找有关 XRX 环境的更多信息。
CSSToXSLFO用户指南:了解关于样式表和格式想法的更多信息。-
XML 新手入门 获取您学习 XML 所需的资源。
- developerWorks 的 XML 专区:查找提升您在 XML 领域技能所需的资源,包括 DTD、模式和 XSLT。参见 XML 技术库,了解更广泛的技术文章和技巧、教程、标准和 IBM 红皮书。
- IBM XML 认证:了解如何成为 XML 和相关技术方面的 IBM 认证开发人员。
- developerWorks 技术活动 和 网络广播:随时关注这些会议中涉及的技术。
- Twitter 上的 developerWorks:立即加入以关注 developerWorks 推文。
- developerWorks 播客:收听面向软件开发人员的有趣访谈和讨论。
- developerWorks 演示中心:观看演示,包括面向初学者的产品安装和设置演示,以及为经验丰富的开发人员提供的高级功能。
获得产品和技术
- eXist XML 数据库网站:下载 eXist 并获取安装说明。
eXist 数字发布模块:从 Google Code 下载。CSSToXSLFO实用工具:从 SourceForge 下载此实用工具。- IBM 产品评估试用版软件:下载或 IBM SOA 人员沙箱,并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
讨论
- developerWorks 概要信息:现在就创建您的概要信息,并建立关注清单。
- XML 专区讨论论坛:参与多个与 XML 相关的讨论。
- developerWorks 中文社区:查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
