【问题】
docbook中,写好了xml源码:
<bookinfo> <title>MPEG简介 + 如何计算CBR和VBR的MP3的播放时间</title> <author><personname><firstname>Crifan</firstname><surname>Li</surname></personname></author> <authorinitials>crl</authorinitials> <revhistory> <revision> <revnumber>1.0</revnumber> <date>2009-09-19</date> <revremark> <orderedlist> <listitem>简介MPEG相关知识</listitem> <listitem>详细介绍如何计算CBR和VBR的MP3的播放时间</listitem> </orderedlist> </revremark> </revision> </revhistory>
也可以生成对应的html和pdf了。
但是对于其中的revhistory所对应的版本历史部分的内容,
html中是可以正常显示的:
但是pdf中却不显示这部分内容。
【解决过程】
1.参考:docbook-apps message,去:
Print title pages Chapter 13. Print customizations
然后又找到了:
Part III. Customizing DocBook XSL – Chapter 11. Title page customization
然后按照其提示,我去:
docbook-xsl-ns-1.76.1\fo
下面的:
titlepage.templates.xml
中,找到了:
<!-- ==================================================================== --> <t:titlepage t:element="book" t:wrapper="fo:block"> <t:titlepage-content t:side="recto"> <title t:named-template="division.title" param:node="ancestor-or-self::book[1]" text-align="center" font-size="&hsize5;" space-before="&hsize5space;" font-weight="bold" font-family="{$title.fontset}"/> <subtitle text-align="center" font-size="&hsize4;" space-before="&hsize4space;" font-family="{$title.fontset}"/> <corpauthor font-size="&hsize3;" keep-with-next.within-column="always" space-before="2in"/> <authorgroup space-before="2in"/> <author font-size="&hsize3;" space-before="&hsize2space;" keep-with-next.within-column="always"/> <!-- If you add editor, include this t:predicate attribute because only the first editor generates the list of editors. <editor t:predicate="[position() = 1]"/> --> </t:titlepage-content> <t:titlepage-content t:side="verso"> <title t:named-template="book.verso.title" font-size="&hsize2;" font-weight="bold" font-family="{$title.fontset}"/> <corpauthor/> <authorgroup t:named-template="verso.authorgroup"/> <author/> <!-- If you add editor, include this t:predicate attribute because only the first editor generates the list of editors. <editor t:predicate="[position() = 1]"/> --> <othercredit/> <releaseinfo space-before="0.5em"/> <pubdate space-before="1em"/> <copyright/> <abstract/> <legalnotice font-size="8pt"/> </t:titlepage-content> <t:titlepage-separator> <fo:block break-after="page"/> </t:titlepage-separator> <t:titlepage-before t:side="recto"> </t:titlepage-before> <t:titlepage-before t:side="verso"> <fo:block break-after="page"/> </t:titlepage-before> </t:titlepage>
然后添加了对应的revision和revhistory,变为:
<!-- ==================================================================== --> <t:titlepage t:element="book" t:wrapper="fo:block"> <t:titlepage-content t:side="recto"> <title t:named-template="division.title" param:node="ancestor-or-self::book[1]" text-align="center" font-size="&hsize5;" space-before="&hsize5space;" font-weight="bold" font-family="{$title.fontset}"/> <subtitle text-align="center" font-size="&hsize4;" space-before="&hsize4space;" font-family="{$title.fontset}"/> <corpauthor font-size="&hsize3;" keep-with-next.within-column="always" space-before="2in"/> <authorgroup space-before="2in"/> <author font-size="&hsize3;" space-before="&hsize2space;" keep-with-next.within-column="always"/> <!-- If you add editor, include this t:predicate attribute because only the first editor generates the list of editors. <editor t:predicate="[position() = 1]"/> --> <revision/> <revhistory/> </t:titlepage-content> <t:titlepage-content t:side="verso"> <title t:named-template="book.verso.title" font-size="&hsize2;" font-weight="bold" font-family="{$title.fontset}"/> <corpauthor/> <authorgroup t:named-template="verso.authorgroup"/> <author/> <!-- If you add editor, include this t:predicate attribute because only the first editor generates the list of editors. <editor t:predicate="[position() = 1]"/> --> <othercredit/> <releaseinfo space-before="0.5em"/> <pubdate space-before="1em"/> <copyright/> <abstract/> <legalnotice font-size="8pt"/> <revision/> <revhistory/> </t:titlepage-content> <t:titlepage-separator> <fo:block break-after="page"/> </t:titlepage-separator> <t:titlepage-before t:side="recto"> </t:titlepage-before> <t:titlepage-before t:side="verso"> <fo:block break-after="page"/> </t:titlepage-before> </t:titlepage>
再去重新生成fo然后pdf,结果还是没有效果,revhistory还是没有显示。
2.后来随便试着把上述的titlepage.templates.xml中弄几个语法错误,然后调用xsltproc编译,结果顺利通过,证明此处根本没有调用到对应的titlepage.templates.xml。所以还是先要搞清楚,真正调用的是哪个文件。
结果去找了下,发现当前用的xsl是:
docbook_crl.xsl
其中是包含了的另外一个xsl:
<xsl:import href="docbook.xsl"/>
而docbook.xsl中,则是:
<xsl:include href="titlepage.xsl"/>
<xsl:include href="titlepage.templates.xsl"/>
而对于titlepage.templates.xsl,又看到有提示:
<!– This stylesheet was created by template/titlepage.xsl—>
然后去找到了template/titlepage.xsl,但是也还是看不懂其内容。
而对于fo下面的titlepage.xsl,也是很复杂,貌似不好修改。
3.参考:Part III. Customizing DocBook XSL – Chapter 11. Title page customization,然后一步步照葫芦画瓢:
(1)拷贝titlepage.templates.xml为titlepage.templates_crl.xml,然后在
<t:titlepage-content t:side="recto">部分添加了:
<revision/> 和<revhistory/>
(2)用命令:
CLi@PC-CLI-1 ~/develop/docbook/tools/docbook-xsl-ns-1.76.1 $ xsltproc --output fo/titlepage.template_crl.xsl template/titlepage.xsl fo/titlepage.templates_crl.xml
去生成了titlepage.template_crl.xsl
(3)将titlepage.template_crl.xsl添加到了docbook_crl.xsl中:
<xsl:import href="titlepage.template_crl.xsl"/>
(4)在调用xsltproc生成fo:
CLi@PC-CLI-1 ~/develop/docbook/books/VBR/VBR/src $ xsltproc.exe --stringparam section.autolabel 1 --stringparam section.label.includes.component.label 1 --stringparam bibliography.numbered 1 --xinclude -o /home/CLi/develop/docbook/books/VBR/VBR/output/fo/MPEG_VBR.fo /home/CLi/develop/docbook/tools/docbook-xsl-ns-1.76.1/fo/docbook_crl.xsl /home/CLi/develop/docbook/books/VBR/VBR/src/MPEG_VBR.xml Making portrait pages on USletter paper (8.5inx11in)
是OK的。
(5)但是去生成pdf就出错了:
CLi@PC-CLI-1 ~/develop/docbook/books/VBR/VBR/src $ D:/tmp/tmp_dev_root/cgwin/home/CLi/develop/docbook/tools/fop/fop.cmd -c D:/tmp/tmp_dev_root/cgwin/home/CLi/develop/docbook/tools/fop/conf/fop.xconf D:/tmp/tmp_dev_root/cgwin/home/CLi/develop/docbook/books/VBR/VBR/output/fo/MPEG_VBR.fo -pdf D:/tmp/tmp_dev_root/cgwin/home/CLi/develop/docbook/books/VBR/VBR/output/pdf/MPEG_VBR.pdf May 4, 2012 1:29:19 PM org.apache.fop.apps.FopFactoryConfigurator configure INFO: Default page-height set to: 11in May 4, 2012 1:29:19 PM org.apache.fop.apps.FopFactoryConfigurator configure INFO: Default page-width set to: 8.26in May 4, 2012 1:29:19 PM org.apache.fop.cli.Main startFOP SEVERE: Exception javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: Property ID "id36018215" (found on "fo:list-block") previously used; ID values must be unique within a document! (See position 9:296) at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:302) at org.apache.fop.cli.InputHandler.renderTo(InputHandler.java:130) at org.apache.fop.cli.Main.startFOP(Main.java:174) at org.apache.fop.cli.Main.main(Main.java:205) Caused by: javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: Property ID "id36018215" (found on "fo:list-block") previously used; ID values must be unique within a document! (See position 9:296) at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:501) at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:299) ... 3 more Caused by: org.apache.fop.fo.ValidationException: Property ID "id36018215" (found on "fo:list-block") previously used; ID values must be unique within a document! (See position 9:296) at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38) at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:54) at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:175) at $Proxy0.idNotUnique(Unknown Source) at org.apache.fop.fo.FObj.checkId(FObj.java:172) at org.apache.fop.fo.FObj.startOfNode(FObj.java:153) at org.apache.fop.fo.flow.ListBlock.startOfNode(ListBlock.java:90) at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.startElement(FOTreeBuilder.java:327) at org.apache.fop.fo.FOTreeBuilder.startElement(FOTreeBuilder.java:171) at org.apache.xalan.transformer.TransformerIdentityImpl.startElement(TransformerIdentityImpl.java:1072) at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source) at org.apache.xerces.xinclude.XIncludeHandler.startElement(Unknown Source) at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:484) ... 4 more ---------
然后去看了对应的fo文件,的确里面有两个id都是id36018215:
<fo:list-block id="id36018215" space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-distance-between-starts="1.2em" provisional-label-separation="0.2em"><fo:list-item id="id36018198" space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em"><fo:list-item-label end-indent="label-end()"><fo:block>1.</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block>简介MPEG相关知识</fo:block></fo:list-item-body></fo:list-item><fo:list-item id="id36018211" space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em"><fo:list-item-label end-indent="label-end()"><fo:block>2.</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"> xxxxxxxxxx <fo:list-block id="id36018215" space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-distance-between-starts="1.2em" provisional-label-separation="0.2em"><fo:list-item id="id36018198" space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em"><fo:list-item-label end-indent="label-end()"><fo:block>1.</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block>简介MPEG相关知识</fo:block></fo:list-item-body></fo:list-item><fo:list-item id="id36018211" space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em"><fo:list-item-label end-indent="label-end()"><fo:block>2.</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block>详细介绍如何计算CBR和VBR的MP3的播放时间</fo:block></fo:list-item-body></fo:list-item></fo:list-block> </fo:block></fo:table-cell></fo:table-row><fo:table-row><fo:table-cell><fo:block>修订 1.4</fo:block></fo:table-cell><fo:table-cell><fo:block>2011-04-24</fo:block></fo:table-cell><fo:table-cell><fo:block/></fo:table-cell></fo:table-row><fo:table-row><fo:table-cell number-columns-spanned="3"><fo:block>
也尝试过,去把docbook_crl.xsl中import titlepage.template_crl.xsl去掉,而手动添加到此处所用到的那个docbook.xsl中,即替换掉
<xsl:include href="titlepage.templates.xsl"/>
或
<xsl:include href="pagesetup.xsl"/>
但却都还是不行。
这是无语了。
4.不过后来手动把那些重复的id改成别的值,比如id36018888,然后就可以生成了对应的pdf了,但是的确是关于revhistory的部分,内容重复了,显示效果如下:
所以,还是要去搞懂,此处为何是重复了。
5.后来,折腾了很长时间,最后无意间才想起来,原来是我在对于book的recto和verso,都添加了对应的revhistory,导致了生成的pdf中,recto所对应的第一页和verso所对应的第二页中,都出现了修订历史。
因此,直接把verso部分的revhistory去掉,即可。
【总结】
想要给docbook的pdf中生成revhistory修订历史的话,此处可简述其逻辑为:
1.新建自己的xml
参考原先自带的titlepage.templates.xml,拷贝一份出来,在:
<t:titlepage t:element="book" t:wrapper="fo:block">
<t:titlepage-content t:side="recto">
部分,添加对应的:
<revhistory>
2.生成相应的xsl
使用xsltproc,根据template/titlepage.xsl,使用上面修改后的xml,生产对应的xsl文件
3. 添加该xsl
将xsl文件添加到你的docbook.xsl文件即可。
4.其余步骤依旧
然后就是按照你之前的步骤了:调用xsltproc生成对应fo,然后再调用fop生成pdf,即可。
具体如何做,请参考:Part III. Customizing DocBook XSL – Chapter 11. Title page customization,