【问题】
折腾docbook,给其添加catalog的支持,以方便映射本地的xsl为一个简单的名称,方便其他地方调用。
但是使用catalog的过程中结果出错:
CLi@PC-CLI-1 ~/develop/docbook/books/VBR/VBR/src $ XML_CATALOG_FILES="/home/CLi/develop/docbook/config/catalog/catalog.xml" XML_DEBUG_CATALOG=1 xsltproc.exe --xinclude -o ../output/html/MPEG_VBR.html docbook_html_crl.xsl MPEG_VBR.xml Resolve: sysID docbook_html_crl.xsl -2147483592 Parsing catalog /home/CLi/develop/docbook/config/catalog/catalog.xml /home/CLi/develop/docbook/config/catalog/catalog.xml:0: element uri: Catalog error : uri entry lacks 'name' /home/CLi/develop/docbook/config/catalog/catalog.xml added to file hash Resolve URI docbook_html_crl.xsl Found URI match docbook_html_crl.xsl Resolve: sysID /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl Resolve URI /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl warning: failed to load external entity "/home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl" compilation error: file /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_crl.xsl line 17 element import xsl:import : unable to load /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl Catalogs cleanup Free catalog entry crl.ent Free catalog entry docbook_fo.xsl Free catalog entry docbook_html_crl.xsl Free catalog entry docbook_fo_crl.xsl Free catalog entry /home/CLi/develop/docbook/config/catalog/catalog.xml Free catalog entry
相关的catalog.xml内容为:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE catalog PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd" [ <!ENTITY config_dir "/home/CLi/develop/docbook/config"> <!ENTITY config_xls_ns_dir "&config_dir;/docbook-xsl-ns-1.76.1"> <!ENTITY xsl_ns_base_dir "/home/CLi/develop/docbook/tools/docbook-xsl-ns-1.76.1"> <!-- <!ENTITY xsl_ns_base_dir "/cygdrive/e/Dev_Root/docbook/tools/docbook-xsl-ns-1.76.1"> --> ] > <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> <public publicId="crl.ent" uri="&config_dir;/entity/crl.ent"/> <uri publicId="docbook_html.xsl" uri="&xsl_ns_base_dir;/html/docbook.xsl"/> <uri name="docbook_fo.xsl" uri="&xsl_ns_base_dir;/fo/docbook.xsl"/> <uri name="docbook_html_crl.xsl" uri="&config_xls_ns_dir;/html/docbook_crl.xsl"/> <uri name="docbook_fo_crl.xsl" uri="&config_xls_ns_dir;/fo/docbook_crl.xsl"/> </catalog>
【解决过程】
1.其中,命令中的docbook_html_crl.xsl,是catalog中配置的:
<uri name="docbook_html_crl.xsl" uri="&config_xls_ns_dir;/html/docbook_crl.xsl"/>
可以看出,是可以被正确解析的。
但是,另外一个xsl配置文件docbook_crl.xsl中所引用的:
<xsl:import href="docbook_html.xsl"/>
却无法正确解析,显示错误:
warning: failed to load external entity "/home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl"
所以,开始是怀疑,用catalog所定义的“别名”,只能在makefile,命令行等环境中使用,而无法在xsl等文件中使用。
但是却又看到这里:DocBook使用笔记,中说:
只需这样写:
<xsl:import href="html/chunk.xsl"/>而不用写成繁琐的
<xsl:import href="/usr/share/sgml/docbook/xsl-stylesheets-1.69.1-5.1/html/chunk.xsl"/>这样做的好处是,可以将样式表的安装路径统一在catalog.xml中规定,不用在每个xsl中重复书写完整路径了。 以后万一要升级样式表,也只需修改catalog.xml中的定义即可,不用去每个xsl中修改。
意思就是这样用的,但是我这里却始终不可以。不知道为何。
2.对于catalog中:
<public publicId="crl.ent" uri="&config_dir;/entity/crl.ent"/>
在别的某个xml文件中,是可以引用成功的:
<!DOCTYPE chapter [ <!-- <!ENTITY % crl_ent SYSTEM "../../../../config/entity/crl.ent">%crl_ent; --> <!ENTITY % crl_ent PUBLIC "crl.ent" 'null'>%crl_ent; ] >
所以,想到,参考其写法,把docbook_html.xsl的定义换成:
<public publicId="docbook_html.xsl" uri="&xsl_ns_base_dir;/html/docbook.xsl"/>
然后在docbook_crl.xsl中引用:
<!DOCTYPE stylesheet [ <!ENTITY % docbook_html PUBLIC "docbook_html.xsl" 'null'>%docbook_html; ]> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'> <xsl:import href="&docbook_html;"/> </xsl:stylesheet>
结果出错:
CLi@PC-CLI-1 ~/develop/docbook/books/VBR/VBR/src $ XML_CATALOG_FILES="/home/CLi/develop/docbook/config/catalog/catalog.xml" XML_DEBUG_CATALOG=1 xsltproc.exe --xinclude -o ../output/html/MPEG_VBR.html docbook_html_crl.xsl MPEG_VBR.xml Resolve: sysID docbook_html_crl.xsl -2147483592 Parsing catalog /home/CLi/develop/docbook/config/catalog/catalog.xml /home/CLi/develop/docbook/config/catalog/catalog.xml:0: element uri: Catalog error : uri entry lacks 'name' /home/CLi/develop/docbook/config/catalog/catalog.xml added to file hash Resolve URI docbook_html_crl.xsl Found URI match docbook_html_crl.xsl Resolve: pubID docbook_html.xsl sysID /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/null Resolve URI /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/null /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_crl.xsl:6: warning: failed to load external entity "/home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/null" <!ENTITY % docbook_html PUBLIC "docbook_html.xsl" 'null'>%docbook_html; ^ Entity: line 1: %docbook_html; ^ /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_crl.xsl:20: parser error : Entity 'docbook_html' not defined <xsl:import href="&docbook_html;"/> ^ compilation error: file /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_crl.xsl line 20 element import xsl:import : recursion detected on imported URL /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_crl.xsl Catalogs cleanup Free catalog entry crl.ent Free catalog entry docbook_fo.xsl Free catalog entry docbook_html_crl.xsl Free catalog entry docbook_fo_crl.xsl Free catalog entry /home/CLi/develop/docbook/config/catalog/catalog.xml Free catalog entry
所以,还是搞不懂,如何实现在别的xsl文件中,引用catalog定义的某个xsl文件的别名。
3.参考:Failed to load external entity "xhtml_onechunk",去试了试xmllint.:
CLi@PC-CLI-1 ~/develop/docbook/books/VBR/VBR/src $ xmllint.exe --valid --noout /home/CLi/develop/docbook/config/catalog/catalog.xml
说明我的catalog是valid的。
4.后来参考:Re: [xslt] [xml] Problem with xsltproc on Windows,把xsl_ns_base_dir去添加file://前缀:
<!ENTITY xsl_ns_base_dir "file:///home/CLi/develop/docbook/tools/docbook-xsl-ns-1.76.1">
结果也还是同样错误。
5.试了试把默认的/etc/xml/catalog也加上,结果还是出错:
CLi@PC-CLI-1 ~/develop/docbook/books/VBR/VBR/src $ XML_CATALOG_FILES="/etc/xml/catalog /home/CLi/develop/docbook/config/catalog/catalog.xml" \ xsltproc.exe --xinclude -o ../output/html/MPEG_VBR.html docbook_html_crl.xsl MPEG_VBR.xml> XML_DEBUG_CATALOG=1 \ > xsltproc.exe --xinclude -o ../output/html/MPEG_VBR.html docbook_html_crl.xsl MPEG_VBR.xml Resolve: sysID docbook_html_crl.xsl -2147483592 Parsing catalog /etc/xml/catalog /etc/xml/catalog added to file hash /home/CLi/develop/docbook/config/catalog/catalog.xml not found in file hash -2147483592 Parsing catalog /home/CLi/develop/docbook/config/catalog/catalog.xml /home/CLi/develop/docbook/config/catalog/catalog.xml added to file hash Resolve URI docbook_html_crl.xsl Found URI match docbook_html_crl.xsl Resolve: sysID /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl Resolve URI /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl warning: failed to load external entity "/home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl" compilation error: file /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_crl.xsl line 19 element import xsl:import : unable to load /home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl Catalogs cleanup Free catalog entry -//OASIS//ENTITIES DocBook Free catalog entry -//OASIS//ELEMENTS DocBook Free catalog entry -//OASIS//DTD DocBook Free catalog entry http://www.oasis-open.org/docbook/ Free catalog entry http://www.oasis-open.org/docbook/ Free catalog entry ISO 8879:1986 Free catalog entry http://docbook.sourceforge.net/release/xsl/ Free catalog entry http://docbook.sourceforge.net/release/xsl/ Free catalog entry http://docbook.sourceforge.net/release/xsl-ns/ Free catalog entry http://docbook.sourceforge.net/release/xsl-ns/ Free catalog entry http://glade.gnome.org/glade-2.0.dtd Free catalog entry /etc/xml/catalog Free catalog entry crl.ent Free catalog entry docbook_html.xsl Free catalog entry docbook_fo.xsl Free catalog entry docbook_html_crl.xsl Free catalog entry docbook_fo_crl.xsl Free catalog entry /home/CLi/develop/docbook/config/catalog/catalog.xml Free catalog entry Free catalog entry
6.折腾了半天,终于想到了一个办法来验证docbook_html.xsl是否可以被正确解析。
通过命令:
CLi@PC-CLI-1 ~/develop/docbook/books/VBR/VBR/src $ XML_CATALOG_FILES="/home/CLi/develop/docbook/config/catalog/catalog.xml" XML_DEBUG_CATALOG=1 xsltproc.exe --xinclude -o ../output/html/MPEG_VBR.html docbook_html.xsl MPEG_VBR.xml Resolve: sysID docbook_html.xsl -2147483592 Parsing catalog /home/CLi/develop/docbook/config/catalog/catalog.xml /home/CLi/develop/docbook/config/catalog/catalog.xml added to file hash Resolve URI docbook_html.xsl Found URI match docbook_html.xsl Resolve: pubID crl.ent sysID null Found public match crl.ent Catalogs cleanup Free catalog entry crl.ent Free catalog entry docbook_html.xsl Free catalog entry docbook_fo.xsl Free catalog entry docbook_html_crl.xsl Free catalog entry docbook_fo_crl.xsl Free catalog entry /home/CLi/develop/docbook/config/catalog/catalog.xml Free catalog entry
就验证了,docbook_html.xsl,是可以在命令行的环境中正确解析的。
而这点,和DocBook 5 快速起步教程 中的解释也是一致的,即catalog中定义的别名,用于xsltproc所使用。
而之前的错误证明了,catalog中的xsl文件别名,是没法在别的xsl文件中引用的,至少是没法被xsl:import的。
【总结】
目前的理解是,catalog中定义的别名,可以在命令行环境中(给xsltproc,makefile,脚本等)所使用。
但是无法用于别的xsl中,即别的xsl中调用该文件别名,是找不到的。默认是就变成了当前路径去找该文件了。
比如我此处的,catalog中定义了:
docbook_html.xsl = file:///home/CLi/develop/docbook/tools/docbook-xsl-ns-1.76.1/html/docbook.xsl
而在xsltproc中是可以被识别的,但是在另外某个xsl文件docbook_crl.xsl中引用:
<xsl:import href="docbook_html.xsl"/>
就会找不到,被识别为docbook_crl.xsl所在的当前路径下面找该文件:
file:///home/CLi/develop/docbook/config/docbook-xsl-ns-1.76.1/html/docbook_html.xsl
因此才会找不到。
解决办法很简单,那就是xsl中,还是用之前的绝对路径去引用对应的xsl文件,而不能调用catalog中的别名。
【后记】
又找到的权威的解释:
1.其中,上述可以通过xsl:import的话,是可以的,但是是针对Xalan的:
2.想要实现去除hardcode,即上述的用(短的)别名代替实际路径中的文件的,是不可以的:
所以,看来还是没法很方便的实现对于xsl中import导入的文件,用短路径或别名的。
【后记2】
另外,之前就参考了:
刚刚看到这句:
The catalog processing mechanism in xsltproc will properly handle short references such as
fo/docbook.xsl
for the stylesheet name on the command line.
那就的确说明了,xsltproc使用catalog的话,那是只支持命令行中的别名替换和解析的,而不支持别的xsl文件中所引用的xsl文件的别名的。
所以,我甚至去试了给catalog添加rewriteURI:
<group xml:base="file:///home/CLi/develop/docbook/tools/docbook-xsl-ns-1.76.1/" > <rewriteURI uriStartString="/tool/xsl_ns/html/" rewritePrefix="html/" /> <uri name="docbook_html.xsl" uri="html/docbook.xsl" /> <uri name="docbook_fo.xsl" uri="fo/docbook.xsl"/> </group>
然后在docbook_crl.xsl中引用:
<xsl:import href="/tool/xsl_ns/html/docbook.xsl"/>
结果也还是无法成功的。
前后的实验结果,证实了,xsltproc中,是不支持xsl文件中引用catalog中的别名的。
转载请注明:在路上 » 【基本解决】docbook中使用catalog.xml时出错:Resolve: sysID xxx, Resolve URI xxx, warning: failed to load external entity