最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【基本解决】docbook中使用catalog.xml时出错:Resolve: sysID xxx, Resolve URI xxx, warning: failed to load external entity

Docbook crifan 1975浏览 0评论

【问题】

折腾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的:

14.Using catalogs with Xalan

2.想要实现去除hardcode,即上述的用(短的)别名代替实际路径中的文件的,是不可以的:

9. Hardcoded import paths

所以,看来还是没法很方便的实现对于xsl中import导入的文件,用短路径或别名的。

【后记2】

另外,之前就参考了:

Using catalogs with xsltproc

刚刚看到这句:

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

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.223 seconds, using 22.38MB memory