如何使用saxon内置目录功能

the*_*eta 2 xml validation dtd saxon xmlcatalog

我下载了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开关,但撒克逊不会看到它.我收到此错误:

查询处理失败:无法加载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.
Run Code Online (Sandbox Code Playgroud)

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

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

Dan*_*ley 5

来自您问题中的saxonica链接:

当在命令行上使用-catalog选项时,这将覆盖Saxon中使用的内部解析器(从9.4开始),以将着名的W3C引用(例如XHTML DTD)重定向到Saxon的这些资源的本地副本.由于这两个功能都依赖于设置XML解析器的EntityResolver,因此无法将它们结合使用.

这听起来像Saxon自动使用众所周知的W3C DTD的本地副本,但如果您指定-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
Run Code Online (Sandbox Code Playgroud)

XML DTD(so_test/lib/test.dtd)

<!ELEMENT test (foo)>
<!ELEMENT foo (#PCDATA)>
Run Code Online (Sandbox Code Playgroud)

XML实例(so_test/test.xml)

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

<!DOCTYPE test PUBLIC "-//TEST//Dan Test//EN" "dir_that_doesnt_exist/test.dtd">
<test>
    <foo>Success!</foo>
</test>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

命令行

请注意-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
Run Code Online (Sandbox Code Playgroud)

结果

<results>Success!</results>
Run Code Online (Sandbox Code Playgroud)

如果我使XML实例无效:

<!DOCTYPE test PUBLIC "-//TEST//Dan Test//EN" "dir_that_doesnt_exist/test.dtd">
<test>
    <x/>
    <foo>Success!</foo>
</test>
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

希望这个例子可以帮助你弄清楚你的设置要改变什么.

此外,使用该-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
Run Code Online (Sandbox Code Playgroud)

附加信息

Saxon分发Apache版本的Xerces,因此请使用Apache Xerces发行版中resolver.jarfound .

  • 更新:Saxon在运行XSLT时会获取其DTD的本地副本,但在运行XQuery时则不然.将在下一个维护版本中修复. (2认同)