【问题】
折腾docbook,给其添加catalog的支持,以方便映射本地的xsl为一个简单的名称,方便其他地方调用。
但是使用catalog的过程中结果出错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <? xml version = "1.0" encoding = "UTF-8" ?> <!DOCTYPE catalog PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN" [ <!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中配置的:
1 2 | < uri name = "docbook_html_crl.xsl" uri = "&config_xls_ns_dir;/html/docbook_crl.xsl" /> |
可以看出,是可以被正确解析的。
但是,另外一个xsl配置文件docbook_crl.xsl中所引用的:
1 | < xsl:import href = "docbook_html.xsl" /> |
却无法正确解析,显示错误:
1 | 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中:
1 2 | < public publicId = "crl.ent" uri = "&config_dir;/entity/crl.ent" /> |
在别的某个xml文件中,是可以引用成功的:
1 2 3 4 5 6 | <!DOCTYPE chapter [ <!-- <!ENTITY % crl_ent SYSTEM "../../../../config/entity/crl.ent">%crl_ent; --> <!ENTITY % crl_ent PUBLIC "crl.ent" 'null'>%crl_ent; ] > |
所以,想到,参考其写法,把docbook_html.xsl的定义换成:
1 2 | < public publicId = "docbook_html.xsl" uri = "&xsl_ns_base_dir;/html/docbook.xsl" /> |
然后在docbook_crl.xsl中引用:
1 2 3 4 5 6 7 8 | <!DOCTYPE stylesheet [ <!ENTITY % docbook_html PUBLIC "docbook_html.xsl" 'null'>%docbook_html; ]> version = '1.0' > < xsl:import href = "&docbook_html;" /> </ xsl:stylesheet > |
结果出错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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.:
1 2 | 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://前缀:
1 | <!ENTITY xsl_ns_base_dir "file:///home/CLi/develop/docbook/tools/docbook-xsl-ns-1.76.1"> |
结果也还是同样错误。
5.试了试把默认的/etc/xml/catalog也加上,结果还是出错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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是否可以被正确解析。
通过命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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:
1 2 3 4 5 6 7 8 9 10 | < 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中引用:
1 | < 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