XQuery/DocBook 到 HTML
外观
< XQuery
您希望将 DocBook 文档转换为 HTML 格式。
我们将使用 XQuery 类型转换变换,将示例实例文档转换为 XQuery 类型转换模块。要开始此过程,您可以使用任何从 XML 架构生成实例文档的工具。然后,您可以编辑此文档以仅包含要转换的元素。然后,您可以通过该工具运行此文件以生成类型转换 XQuery 模块。
我们的主要调度函数将具有以下结构
declare namespace db="http://docbook.org/ns/docbook";)
declare function db2html:transform($nodes as node()*) as item()* {
for $node in $nodes
return
typeswitch($node)
case text() return $node
case element(db:article) return db2html:article($node)
case element(db:book) return db2html:book($node)
case element(db:info) return db2html:info($node)
case element(db:para) return db2html:para($node)
case element(db:sect1) return db2html:sect1($node)
case element(db:title) return () (: all titles will be transformed by their parent node :)
case element(db:emphasis) return db2html:emphasis($node)
default return <u>{$node}</u>
};
注意以下几点
- transform 函数以节点序列作为参数,并且对每个节点都返回类型转换函数。
- transform 返回一个项目序列
- 默认操作是将节点从输入复制到输出。不在 case 语句中的所有节点都将无修改地传递。您可以通过更改 default 返回的类型来更改此默认行为。
- 对于每个元素,都会调用一个单独的函数“元素函数”。如果元素是叶元素,则它们可以只返回叶元素的内容。如果不是叶元素,则必须为它们包含的每个子分支调用 transform。通过更改每个函数,您可以更改该元素创建的输出。这种结构使您的转换模块化,易于维护。
- 每个元素的命名空间都是 Docbook 命名空间 (db 是与 DocBook 5 URL http://docbook.org/ns/docbook 关联的前缀)
- 不在 case 语句中的所有元素都将返回一个“u”用于未知元素包装器。这使得它们在调试时易于识别。
每个元素函数都有一个简单的结构。例如,<para> 元素可能具有以下结构
declare function db2html:para($node as node()) as element() {
<p>
{db2html:transform($node/node())}
</p>
};
这将把所有 <db:para> 节点转换为 <p> 节点。请注意,输入类型是 node(),返回类型是 element()。另请注意,由于 <para> 元素包含其他子节点(元素和文本),因此它们都由对 db2html:transform($node/node()) 的递归调用进行处理。
以下是上述模块的函数完整列表。
declare function db2html:article($node as node()) as element() {
<div class="article">
{db2html:transform($node/node())}
</div>
};
declare function db2html:book($node as node()) as element() {
<div class="book">
{db2html:transform($node/node())}
</div>
};
declare function db2html:info($node as node()) as element() {
<div class="info">
<h1>{$node/db:title/text()}</h1>
</div>
};
declare function db2html:sect1($node as node()) as element() {
<div class="sect1">
<h2>{$node/db:title/text()}</h2>
{db2html:transform($node/node())}
</div>
};
declare function db2html:title($node as node()) as element() {
<div class="title">
{db2html:transform($node/node())}
</div>
};
declare function db2html:para($node as node()) as element() {
<p>
{db2html:transform($node/node())}
</p>
};
declare function db2html:emphasis($node as node()) as element() {
<b>
{db2html:transform($node/node())}
</b>
};
<article xmlns="http://docbook.org/ns/docbook" version="5.0">
<info>
<title>Article Template Title</title>
</info>
<sect1>
<title>Section1 Title</title>
<para>Typewsitch transforms are <emphasis role="bold">very</emphasis> powerful.</para>
</sect1>
</article>
要调用转换,您只需将 DocBook 文档的根节点传递给函数即可
let $input := doc('/db/my-docbook-5-document.xml')/db:article
let $output := db2html:transform($input)
return $output
请注意,您必须在 doc() 函数之后放置要转换的根元素。如果没有,doc() 函数将返回一个文档节点,该节点将与任何文档 case 语句都不匹配。
<div class="article">
<div class="info">
<h1>Article Template Title</h1>
</div>
<div class="sect1">
<h2>Section1 Title</h2>
<p>Typewsitch transforms are <b>very</b>powerful.</p>
</div>
</div>
此示例在 Google Code 上的源代码:http://code.google.com/p/xrx/source/browse/#svn%2Ftrunk%2F21-docbook-2-html
Chis Wallace 提供了一个工具,可以将 XML Docbook 转换为类型转换,如下所示:生成骨架类型转换转换模块