对Docbook元素树分支进行XSL转换
我想用docbook的XSL样式表来渲染文档的不同部分,而不是把整个文档都转换。
问题是,有些部分包含了<footnoteref>
元素,而这些元素的linkend
属性并不在同一块内容里。换句话说,我想处理一部分树状结构,这部分包括<footnoteref>
,但不包括它们所引用的<footnote>
元素。
我尝试用Python的lxml
库来实现这个功能,但遇到了这个错误信息:
XSLTApplyError Traceback (most recent call last)
/var/www/mpd/<ipython console> in <module>()
/var/www/mpd/<ipython console> in <genexpr>((elt,))
/usr/lib/python2.6/dist-packages/lxml/etree.so in lxml.etree.XSLT.__call__ (src/lxml/lxml.etree.c:109204)()
XSLTApplyError: Internal error in xsltKeyFunction(): Could not get the document info of a context doc.
这个错误是在执行,比如说etree.XSLT(etree.parse('docbook.xsl'))(some_element)
时出现的。
我使用的是普通的xhtml
样式表。我不认为使用哪个样式表会有什么影响。
有没有什么支持的方法来做到这一点?或者我是不是应该先对文档应用XSLT转换,把<footnoteref>
元素转换成<footnote>
元素,然后再进行渲染?但这样做又不行,因为那样会出现多个相同ID的<footnote>
标签。这个转换只能在<footnote>
标签不被包含在结果树中时进行。我本来以为这已经是默认的行为了。不过希望我只是漏掉了某个设置。
编辑
感谢@Jukka的回答,我发现我可以传递rootid
参数给XSLT处理器,只渲染那个ID的内容。然而,这样做的效果太忠实了,输出的内容只是引用了脚注,和如果整个文档作为一个HTML页面渲染时的片段是一样的。比如说:
>>> xsl_url_html = 'http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl'
>>> from lxml import etree
>>> consume_result = etree.XSLT(etree.parse(xsl_url_xhtml))(
etree.parse(my_xml_file), rootid=etree.XSLT.strparam("command_consume"))
>>> etree.tostring(consume_result).split('\n')
['<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
'<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ASCII" /><title></title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /></head><body><dt><a id="command_consume"></a><span class="term">',
' <div class="cmdsynopsis"><p><code class="command">consume</code> {<em class="replaceable"><code>STATE</code></em>}</p></div>',
' </span></dt><dd><p>',
' <sup>[<a href="#ftn.since_0_15" class="footnoteref">2</a>]</sup>',
' Sets consume state to <code class="varname">STATE</code>,',
' <code class="varname">STATE</code> should be 0 or 1.',
'\t When consume is activated, each song played is removed from playlist.',
' </p></dd></body></html>']
也许还有其他参数可以让脚注在同一页面上显示,最好是从1开始编号?我想这个参数可能在这个列表中的某个地方。我会找时间去看看。
1 个回答
与其试图把DocBook XSL样式表应用到单个元素上,不如把它应用到整个文档上,但可以用rootid
参数来指定你想要转换的文档部分。
根据参考文档的说明:
整个文档会被加载和解析,但格式化会从你指定的元素开始,而不是从文档的根部开始。例如,这样可以只处理一本书的第4章。
因为整个文档都可以被处理器访问,所以自动编号、交叉引用和其他依赖关系都能正确解决。