Skip to main content
 首页 » 编程设计

python之对 Docbook 元素树的一个分支进行 XSL 转换

2025年05月04日11Leo_wl

我想使用 docbook XSL 样式表来呈现文档的各个部分,而不需要转换整个文档。

复杂的是其中一些部分有 <footnoteref> linkend 的元素属性不在同一个 block 中。换句话说,我想处理包含 <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>做这个渲染之前的元素?但那是行不通的,因为那样会有多个 <footnote>具有相同 ID 的标签。它只需要这样做<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 中某处。当我有更多时间时,我会完成它。

请您参考如下方法:

与其尝试将 DocBook XSL 样式表应用于单个元素,不如将其应用于整个文档,但要使用 rootid 指定要转换的文档部分。范围。

来自引用文档:

The entire document will be loaded and parsed, but formatting will begin at the element identified, rather than at the root. For example, this allows you to process only chapter 4 of a book.

Because the entire document is available to the processor, automatic numbering, cross references, and other dependencies are correctly resolved.