如何在Python中使用Amara库验证XML文件与XSD模式?
这个问题的悬赏很高:
你好,
我在使用Python 2.6和Amara2的Ubuntu 9.10上尝试了以下内容:
g@spot:~$ cat test.xml; echo =====o=====; cat test.xsd; echo ====
o=====; cat test.py; echo =====o=====; ./test.py; echo =====o=====
<?xml version="1.0" encoding="utf-8"?>==; ./test.py` >
test.txttest.xsd; echo ===
<test>abcde</test>
=====o=====
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="test" type="xs:NCName"/>
</xs:schema>
=====o=====
#!/usr/bin/python2.6
# I wish to validate an xml file against an external XSD schema.
from amara import bindery, parse
source = 'test.xml'
schema = 'test.xsd'
#help(bindery.parse)
#doc = bindery.parse(source, uri=schema, validate=True) # These 2 seem
to fail in the same way.
doc = parse(source, uri=schema, validate=True) # So, what is the
difference anyway?
#
=====o=====
Traceback (most recent call last):
File "./test.py", line 14, in <module>
doc = parse(source, uri=schema, validate=True)
File "/usr/local/lib/python2.6/dist-packages/Amara-2.0a4-py2.6-linux-
x86_64.egg/amara/tree.py", line 50, in parse
return _parse(inputsource(obj, uri), flags,
entity_factory=entity_factory)
amara.ReaderError: In file:///home/g/test.xml, line 2, column 0:
Missing document type declaration
g@spot:~$
=====o=====
那么,我为什么会看到这个错误呢?这个功能是不是不支持?
我该如何在能够灵活指定任何XSD文件的情况下,验证一个XML文件是否符合XSD的要求呢?
谢谢,如果你有问题请告诉我。
2 个回答
1
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="test" type="xs:NCName"/>
</xs:schema>
我建议你使用 noNamespaceSchemaLocation 属性来把 XML 文件和 XSD 模式绑定在一起。这样你的 XML 文件 test.xml 就会是:
<?xml version="1.0" encoding="utf-8"?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="test.xsd">abcde</test>
而文件 test.xsd 应该放在和 test.xml 同一个文件夹里。这是一种常见的方法,用来在 XML 文件中引用 XML 模式,这在 Python 中也能正常工作。
这样做的好处是,你不需要为每个 XML 文件都知道模式文件。在解析 XML 文件时(使用 etree.parse
),它会自动找到这个模式文件。
5
如果你愿意使用除了 amara 以外的其他库,可以试试 lxml。这个库可以很简单地支持你想要做的事情:
from lxml import etree
source_file = 'test.xml'
schema_file = 'test.xsd'
with open(schema_file) as f_schema:
schema_doc = etree.parse(f_schema)
schema = etree.XMLSchema(schema_doc)
parser = etree.XMLParser(schema = schema)
with open(source_file) as f_source:
try:
doc = etree.parse(f_source, parser)
except etree.XMLSyntaxError as e:
# this exception is thrown on schema validation error
print e