DocBook转PDF时<linegroup>报错:fo:list-item-label缺少子元素
解决DocBook 转PDF时FOP报错的问题
问题背景
使用DocBook 5.2转FO再生成PDF时,FOP抛出以下错误:
"fo:list-item-label" is missing child elements. Required content model: marker* (%block;)+
执行的转换命令:
xsltproc -o db0.fo /usr/share/xml/docbook/stylesheet/docbook-xsl-ns/fo/docbook.xsl db0.xml fop -pdf db0.pdf -fo db0.fo
环境为Debian稳定版,使用docbook-xml-ns 1.79.2和fop 2.6-2,测试XML包含<linegroup>元素,需用该元素排版带行内标记(脚注、强调等)的诗节,无法使用<literallayout>。
报错原因
DocBook XSL的FO样式表默认将<linegroup>转换为fo:list-block列表结构,但未给fo:list-item-label生成任何块级子元素,而FOP严格要求该标签必须包含至少一个块元素,因此触发错误。
解决方法
方法1:通过XSL参数将渲染为普通块
直接设置linegroup.as.blocks参数为true,让样式表把<linegroup>下的每一行转为独立的fo:block,完全避开列表结构:
xsltproc --stringparam linegroup.as.blocks true -o db0.fo /usr/share/xml/docbook/stylesheet/docbook-xsl-ns/fo/docbook.xsl db0.xml
之后执行FOP转换即可生成正常PDF,且完全支持行内标记。
方法2:给添加role属性
给<linegroup>添加role="poetry"属性,样式表会为诗歌类linegroup生成合法的列表标签结构:
<linegroup role="poetry"> <line>Line 1</line> <line>Line 2</line> </linegroup>
重新执行原转换命令即可完成正常转换。
方法3:自定义XSL模板覆盖默认处理
创建自定义样式表custom.xsl,修改<line>的列表项模板,给fo:list-item-label添加空块以满足FOP的内容要求:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:db="http://docbook.org/ns/docbook" version="1.0"> <xsl:import href="/usr/share/xml/docbook/stylesheet/docbook-xsl-ns/fo/docbook.xsl"/> <xsl:template match="db:line" mode="linegroup.list.item"> <fo:list-item> <fo:list-item-label end-indent="label-end()"> <fo:block/> <!-- 空块满足FOP的内容模型要求 --> </fo:list-item-label> <fo:list-item-body start-indent="body-start()"> <fo:block> <xsl:apply-templates/> </fo:block> </fo:list-item-body> </fo:list-item> </xsl:template> </xsl:stylesheet>
使用自定义样式表执行转换:
xsltproc -o db0.fo custom.xsl db0.xml
内容的提问来源于stack exchange,提问作者eudoxos
相关产品推荐
相关产品推荐

