对Docbook元素树的分支执行XSL转换

时间:2010-07-29 03:41:31

标签: python lxml docbook xslt

我想使用docbook XSL样式表来渲染文档的各个部分,而不会改变整个文档。

复杂的是,其中一些部分具有<footnoteref>个元素,其linkend个属性不在同一个块中。换句话说,我想处理树的一个分支,其中包含<footnoteref> s而不是它们引用的<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>个标签。如果<footnoteref>标记未包含在结果树中,则必须仅执行<footnote><footnote>转换。我预计会发生这种情况。但希望我在某个地方错过了一个开关。

修改

感谢@ Jukka的回答,我发现我可以通过rootid参数告诉XSLT处理器只呈现该ID。但是,它也非常忠实地生成输出,只是引用了脚注,并且使用相同的片段,如果将文档呈现为单个HTML页面则该片段非常有用。 EG

>>> 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开始编号?我想它可能会在this list的某个地方。当我有更多时间时,我会经历它。

1 个答案:

答案 0 :(得分:0)

您可以将DocBook XSL样式表应用于单个元素,而不是尝试将其应用于完整文档,而是使用rootid参数指定要转换的文档部分。

参考文献:

  

将加载整个文档   已解析,但格式化将从   确定的元素,而不是   根。例如,这允许你   只处理一本书的第4章。

     

因为整个文件都是   可供处理器使用,自动   编号,交叉引用等   正确解决了依赖关系。