在 Python 中使用 Saxon C HE 时没有 DTD 验证和 XInclude 解析

No DTD validation and XInclude resolution when using Saxon C HE with Python

我对 Python 的 Saxon C HE 版本有疑问。 成功安装后,我尝试了一些执行 XSLT 转换的示例。 这些都奏效了。

但是,当我解析一个 XML 文件时,在解析过程中没有执行 DTD 验证,也没有解析 XIncludes。 我已经尝试了很多东西,但是我不可能解决这个问题。我希望有人能告诉我并解释我的错误。

附件是一个示例,该示例在完成 DTD 验证时应显示意图错误,因为 DTD 中没有名称为 FOU 的元素。 当我 运行 脚本时,它会创建一个 Result.xml 文件,并且存在错误的 FOU 元素和未解析的 XInclude。

我知道使用 lxml 很容易做到这一点,但是我想知道它如何与 Saxon 解析器一起工作。

XML师傅:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE TEST SYSTEM "Test.dtd">
<TEST>
    <FOU Id="A-1">
        <BAR Name="Test-Bar-1"/>
        <BAR Name="Test-Bar-2"/>
        <BAR Name="Test-Bar-3"/>
    </FOU>
    <TUTU Id="TU-1">
        <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Include.xml" xpointer="xpointer(/node()/node()/*)"/>
    </TUTU>
</TEST>

XML包括:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE TEST SYSTEM "Test.dtd">
<TEST>
    <TUTU Id="TU-1">
        <TITI Name="Titi-1"/>
        <TITI Name="Titi-2"/>
        <TITI Name="Titi-3"/>
    </TUTU>
</TEST>

DTD:

<!ELEMENT TEST  (FOO+ , TUTU+)>
<!ELEMENT FOO   (BAR+)>
<!ELEMENT BAR   ANY>
<!ELEMENT TUTU  (TITI+)>
<!ELEMENT TITI  ANY>
<!-- Attribute -->
<!ATTLIST TEST
>
<!ATTLIST FOO
    Id      ID    #REQUIRED
>
<!ATTLIST BAR
    Name        CDATA #IMPLIED
>
<!ATTLIST TUTU
    Id      ID    #REQUIRED
>
<!ATTLIST TITI 
    Name        CDATA #IMPLIED
>

Python 脚本:

import saxonc

with saxonc.PySaxonProcessor(license=False) as proc:
    print(proc.version)
    xdmAtomicval = proc.make_boolean_value(False)
    xsltproc = proc.new_xslt_processor()
    document = proc.parse_xml(xml_file_name='Master.xml')
    print(document)
    
    xsltproc.set_source(xdm_node=document)
    xsltproc.set_output_file("Result.xml")
    xsltproc.compile_stylesheet(stylesheet_file="styl.xslt")
    xsltproc.transform_to_file(stylesheet_file="styl.xslt")
    
    documentRes = proc.parse_xml(xml_file_name='Result.xml')
    print(documentRes)

您应该能够将 xidtd configuration properties 设置为“开”。

proc.set_configuration_property("xi", "on")
proc.set_configuration_property("dtd", "on")

但是,我让它工作的唯一方法是从 xinclude 中删除 xpointer。我没有时间研究为什么这不起作用。

parse_xml() 似乎也没有进行任何验证或 xinclude 解析,但它确实发生在转换中(将 dtd 验证设置为“关闭”或“恢复”以获取 Result.xml).

这是我用来测试的 Python 的修改版本...

import os
import saxonc

with saxonc.PySaxonProcessor(license=False) as proc:
    print(proc.version)
    proc.set_cwd(os.getcwd())
    proc.set_configuration_property("xi", "on")
    proc.set_configuration_property("dtd", "on")

    document = proc.parse_xml(xml_file_name='Master.xml')
    print(document)

    xsltproc = proc.new_xslt30_processor()
    xsltproc.transform_to_file(source_file="Master.xml", stylesheet_file="styl.xslt", output_file="Result.xml")

    documentRes = proc.parse_xml(xml_file_name='Result.xml')
    print(documentRes)

SaxonC 11 中新增的PyDocumentBuilder class 应该可以让您进行DTD 验证。参见:https://www.saxonica.com/saxon-c/doc11/html/saxonc.html#PyDocumentBuilder 您应该可以使用 dtd_validation 方法来设置验证。

您可以按如下方式创建 PyDocumentBuilder:

proc.new_document_builder