DTD验证失败(Python)

4
我是一名能够翻译文本的帮助助手。
我正在编写一个Python脚本,以生成从作为输入传递的XML + DTD的文件,但它失败了,因为DTD无法得到验证,而我在外观上没有看到任何问题。
以下是我的代码:
DTD = 'scenario.dtd'

def OpenXML(xmlDesc):
    dtd = libxml2.parseDTD(None,DTD)
    ctxt = libxml2.newValidCtxt()
    doc = libxml2.parseDoc(xmlDesc)

    frags = doc.xpathEval('/scenario/config_script/param/*')
    for frag in frags:
        frag.unlinkNode()   # We remove children of param for validation

    if doc.validateDtd(ctxt, dtd) != 1:
        print "ERROR : DTD Validation failed ! "
        sys.exit()

    doc.freeDoc()
    dtd.freeDtd()

    return libxml2.parseFile(xmlDesc)

以下是DTD和我作为参数传递的XML字符串(xmlDesc):

原始DTD(scenario.dtd)

 <!ELEMENT scenario (name, description, config_script*)>
 <!ELEMENT name (#PCDATA)>
 <!ELEMENT description (#PCDATA)>
 <!ELEMENT config_script (param)>
 <!ELEMENT param ANY>

 <!ATTLIST scenario target (win32|win64|linux32|linux64) "win32">
 <!ATTLIST config_script name CDATA #REQUIRED>
 <!ATTLIST config_script repository CDATA #REQUIRED>

DTD变量的值(函数第一行)

<!DOCTYPE none SYSTEM "scenario.dtd" [
 <!ELEMENT scenario (name, description, config_script*)>
 <!ELEMENT name (#PCDATA)>
 <!ELEMENT description (#PCDATA)>
 <!ELEMENT config_script (param)>
 <!ELEMENT param ANY>

 <!ATTLIST scenario target (win32|win64|linux32|linux64) "win32">
 <!ATTLIST config_script name CDATA #REQUIRED>
 <!ATTLIST config_script repository CDATA #REQUIRED>

]>

XML(可扩展标记语言)

<config_scripts>
    <script name="reset" repository="config_os">
        <param>
            <user>
                <name/>
                <full_name/>
                <password/>
                <groups/>
            </user>
        </param>
    </script>
</config_scripts>

我最终遇到了这个错误 -> 错误:DTD验证失败!

此外,我可以在控制台中读到以下内容:

No declaration for element config_script
No declaration for element script
No declaration for attribute name of element script
No declaration for attribute repository of element script
No declaration for element user 
No declaration for element full_name
No declaration for element password
No declaration for element groups

据我所知,它们被声明为空。或者是因为我把所有标记都留空了?

有什么想法吗?

最好的问候和谢意


一个使用 lxml 验证 XML 的天真代码也失败了。 - jfs
可能是因为dtd = libxml2.parseDTD(None,DTD)这行代码自动添加了DOCTYPE。 - user740316
您的 DTD 无法验证,但 @DevNull 的可以。 - jfs
1个回答

1

我不确定 Python 代码是否有问题,但我可以告诉你 DTD 的问题在哪里。

首先,你的文档类型声明应该与根元素的名称匹配。你写的是 none,但你的根元素是 config_scripts

你在 "scenario.dtd" 中指定了 scenario.dtd。你应该删除系统标识符。

在你的 XML 中,你有一个未定义的 script 元素。虽然你确实定义了一个 config_script,但 XML 或 DTD 需要更改其中之一。我在我的示例中更改了 DTD。(我还合并了 ATTLIST 声明。)

此外,你还没有定义这些元素:userfull_namepasswordgroups

以下是 DTD 应该看起来的样子(没有对 XML 进行任何修改):

<!DOCTYPE config_scripts [
<!ELEMENT scenario (name, description, config_script*)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT config_scripts (script)>

<!ELEMENT script (param)>
<!ATTLIST script 
           name CDATA #REQUIRED
           repository CDATA #REQUIRED> 

<!ELEMENT param ANY>

<!ELEMENT user (name,full_name,password,groups)>
<!ELEMENT full_name (#PCDATA)>
<!ELEMENT password (#PCDATA)>
<!ELEMENT groups (#PCDATA)>

<!ATTLIST scenario target (win32|win64|linux32|linux64) "win32">
]>

XML在oXygen中针对此DTD进行验证,因此如果需要进行其他更改,则很可能需要在Python代码中进行。


系统标识符是由 Python 中的 dtd = libxml2.parseDTD(None,DTD) 行自动生成的...实际上,我发布的不是我的原始 DTD,而是在函数的第一行分配给 dtd 变量的值。 - user740316

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接