【问题标题】:How to use saxon built-in catalog feature如何使用撒克逊内置目录功能
【发布时间】:2013-01-04 22:06:58
【问题描述】:

我下载了 SaxonHE9-4-0-6J 并想在 CLI 上处理 XHTML。但是,Saxon 尝试从 W3C 加载 DTD,并且每个简单命令都需要花费太多时间。

我有 xml 目录,我通过设置指向目录文件的 env 变量成功地使用了 xmllint,但我不知道如何让 Saxon 使用它。谷歌揭示了与撒克逊人一起使用目录的整个变化历史(因此混乱),没有一个让我高兴。

我下载了resolver.jar 并将其设置在我的CLASSPATH 中,但我无法让Saxon 使用它。 经过各种组合后,我只使用目录变量来关注http://www.saxonica.com/documentation/sourcedocs/xml-catalogs.xml,例如:

-catalog:path-to-my-catalog

(尝试了 URI 和常规路径),并且没有设置 -r-x-y 开关,但 Saxon 没有看到它。我收到此错误:

查询处理失败:未能加载 Apache 目录解析器 图书馆

resolver.jar 在我的类路径中设置,我可以从命令行使用它:

C:\temp>java org.apache.xml.resolver.apps.resolver
Usage: resolver [options] keyword

Where:

-c catalogfile  Loads a particular catalog file.
-n name         Sets the name.
-p publicId     Sets the public identifier.
-s systemId     Sets the system identifier.
-a              Makes the system URI absolute before resolution
-u uri          Sets the URI.
-d integer      Set the debug level.
keyword         Identifies the type of resolution to perform:
                doctype, document, entity, notation, public, system,
                or uri.

OTOH,Saxon 存档本身已经包含 XHTML 和其他各种 DTD,因此必须有简单的方法来摆脱这种挫败感。

如何在命令行中使用 Saxon 并指示它使用本地 DTD?

【问题讨论】:

  • 你能举一个你的命令行例子吗?
  • java -cp saxon9he.jar net.sf.saxon.Query -s:source.html -qs:"query string" 附加开关变体不成功,试图指示使用本地目录

标签: xml validation dtd saxon xmlcatalog


【解决方案1】:

来自您问题中的 saxonica 链接:

在命令行上使用 -catalog 选项时,它会覆盖 Saxon 中使用的内部解析器(从 9.4 开始)重定向众所周知的 W3C 对 Saxon 的本地副本的引用(例如 XHTML DTD) 这些资源。因为这两个特性都依赖于设置 XML 解析器的 EntityResolver,不能在 连词。

这听起来像撒克逊自动使用 well-known W3C DTDs 的本地副本,但如果您指定 -catalog,它不会使用内部解析器,您必须在目录中明确指定这些。


这是一个在 Saxon 中使用目录的工作示例...

我的示例的文件/目录结构

C:/so_test/lib
C:/so_test/lib/catalog.xml
C:/so_test/lib/resolver.jar
C:/so_test/lib/saxon9he.jar
C:/so_test/lib/test.dtd
C:/so_test/test.xml

XML DTD (so_test/lib/test.dtd)

<!ELEMENT test (foo)>
<!ELEMENT foo (#PCDATA)>

XML 实例 (so_test/test.xml)

请注意,系统标识符指向一个不存在的位置,以确保目录正在被使用。

<!DOCTYPE test PUBLIC "-//TEST//Dan Test//EN" "dir_that_doesnt_exist/test.dtd">
<test>
    <foo>Success!</foo>
</test>

XML 目录 (so_test/lib/catalog.xml)

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
    <group prefer="public" xml:base="file:///C:/so_test/lib">
        <public publicId="-//TEST//Dan Test//EN" uri="lib/test.dtd"/>
    </group>
</catalog>

命令行

注意-dtd 选项以启用验证。

C:\so_test>java -cp lib/saxon9he.jar;lib/resolver.jar net.sf.saxon.Query -s:"test.xml" -qs:"<results>{data(/test/foo)}</results>" -catalog:"lib/catalog.xml" -dtd

结果

<results>Success!</results>

如果我使 XML 实例无效:

<!DOCTYPE test PUBLIC "-//TEST//Dan Test//EN" "dir_that_doesnt_exist/test.dtd">
<test>
    <x/>
    <foo>Success!</foo>
</test>

并运行与上面相同的命令行,结果如下:

Recoverable error on line 4 column 6 of test.xml:
  SXXP0003: Error reported by XML parser: Element type "x" must be declared.
Recoverable error on line 6 column 8 of test.xml:
  SXXP0003: Error reported by XML parser: The content of element type "test" must match "(foo)".
Query processing failed: The XML parser reported two validation errors

希望这个示例能帮助您弄清楚要对您的设置进行哪些更改。

此外,使用 -t 选项可以为您提供其他信息,例如加载的目录以及是否解析了公共标识符:

Loading catalog: file:///C:/so_test/lib/catalog.xml
Saxon-HE 9.4.0.6J from Saxonica
Java version 1.6.0_35
Analyzing query from {<results>{data(/test/foo)}</results>}
Analysis time: 122.70132 milliseconds
Processing file:/C:/so_test/test.xml
Using parser org.apache.xml.resolver.tools.ResolvingXMLReader
Building tree for file:/C:/so_test/test.xml using class net.sf.saxon.tree.tiny.TinyBuilder
Resolved public: -//TEST//Dan Test//EN
        file:/C:/so_test/lib/test.dtd
Tree built in 0 milliseconds
Tree size: 5 nodes, 8 characters, 0 attributes
<?xml version="1.0" encoding="UTF-8"?><results>Success!</results>Execution time: 19.482079ms
Memory used: 20648808

其他信息

Saxon distributes the Apache version of Xerces,所以请使用Apache Xerces distribution 中的resolver.jar

【讨论】:

  • 谢谢丹尼尔。我不知道如何指示 Saxon 使用它自己的本地知名 DTD 副本,而且它肯定不会默认使用它们(没有 -catalog 开关)。我按照您的示例代码得到了结果,我的问题显然是,虽然 resolver.jar 在我的系统 CLASSPATH 中,但除了 saxon9he.jar 之外,我还需要使用 -cp 指向 resolver.jar 来调用 java。
  • 更新:Saxon 会在您运行 XSLT 时获取其本地 DTD 副本,但在您运行 XQuery 时不会。将在下一个维护版本中修复。
  • @DanielHaley:谢谢丹尼尔,我已经链接了bug report,其中包括“更新”:) 干杯
  • @DanielHaley 你从哪里得到resolver.jar?可以分享一下链接吗?
  • @yegor256 - 我通常也使用 maven 来处理依赖关系,但这个问题是关于从命令行使用 Saxon。如果您查看Saxon's POM,您会看到"xml-resolver" 是一个依赖项。因此,在您的情况下,您可能想要寻找“xml-resolver-1.2.jar”。
【解决方案2】:

Daniel Haley 比我更好地回答了如何在 Saxon 中使用显式目录。

至于使用众所周知的 DTD 的内置副本,如果 Saxon 9.4 识别出所需资源的系统 ID 或公共 ID,它确实会默认自动执行此操作。如果要访问 W3C 站点,我们首先需要发现的是您使用的 DOCTYPE 的精确形式。

有关加载 Apache 目录解析器失败的错误消息实际上意味着 Saxon 无法加载类 org.apache.xml.resolver.CatalogManager。我想知道您是否正在使用不包含此类的解析器版本?我想不出任何其他解释。

【讨论】:

  • 这是文档的文档类型:&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;。解析器报告为XmlResolver 1.2。我在里面看到 org.apache.xml.resolver.CatalogManager 类,如果我在调用 Saxon 时在 -cp 开关中添加 resolver.jar,它工作正常,正如我之前评论的那样。
  • DOCTYPE 看起来不错,应该会触发 Saxon 自动使用本地副本。如果没有,请在saxonica.plan.io 上报告,以便我们进行调查。关于加载 resolver.jar 的问题,我不确定是什么问题 - 您的最新评论表明它正在正常工作。
  • Michael,我打开了问题:saxonica.plan.io/issues/1673 关于解析器:我希望如果 resolver.jar 在我的 CLASSPATH 中,我在调用 Saxon 时不必再次添加它。这是 CLI 会话 screenshot
  • @MichaelKay 你能告诉我resolver.jar的位置吗?
  • 转到 findjar.com 并搜索 xml-resolver-1.2.jar
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多