我在另一个文件中有一个XML文件和一个XML模式,我想验证我的XML文件是否符合模式。我如何在Python中执行此操作?
我更喜欢使用标准库的东西,但如果需要,我可以安装第三方软件包。
答案 0 :(得分:54)
我假设您的意思是使用XSD文件。令人惊讶的是,支持这一点的python XML库并不多。然而,lxml确实如此。检查Validation with lxml。该页面还列出了如何使用lxml来验证其他模式类型。
答案 1 :(得分:25)
至于“纯python”解决方案:包索引列表:
答案 2 :(得分:15)
安装lxml
pip install lxml
如果您收到类似的错误“无法在库libxml2中找到函数xmlCheckVersion。是否安装了libxml2?”,请先尝试执行此操作:
# Debian/Ubuntu
apt-get install python-dev python3-dev libxml2-dev libxslt-dev
# Fedora 23+
dnf install python-devel python3-devel libxml2-devel libxslt-devel
最简单的验证器
让我们创建最简单的 validator.py
from lxml import etree
def validate(xml_path: str, xsd_path: str) -> bool:
xmlschema_doc = etree.parse(xsd_path)
xmlschema = etree.XMLSchema(xmlschema_doc)
xml_doc = etree.parse(xml_path)
result = xmlschema.validate(xml_doc)
return result
然后编写并运行 main.py
from validator import validate
if validate("path/to/file.xml", "path/to/scheme.xsd"):
print('Valid! :)')
else:
print('Not valid! :(')
一点点OOP
为了验证多个文件,每次都不需要创建 XMLSchema 对象,因此:
<强> validator.py 强>
from lxml import etree
class Validator:
def __init__(self, xsd_path: str):
xmlschema_doc = etree.parse(xsd_path)
self.xmlschema = etree.XMLSchema(xmlschema_doc)
def validate(self, xml_path: str) -> bool:
xml_doc = etree.parse(xml_path)
result = self.xmlschema.validate(xml_doc)
return result
现在我们可以验证目录中的所有文件,如下所示:
<强> main.py 强>
import os
from validator import Validator
validator = Validator("path/to/scheme.xsd")
# The directory with XML files
XML_DIR = "path/to/directory"
for file_name in os.listdir(XML_DIR):
print('{}: '.format(file_name), end='')
file_path = '{}/{}'.format(XML_DIR, file_name)
if validator.validate(file_path):
print('Valid! :)')
else:
print('Not valid! :(')
有关更多选项,请参阅此处:Validation with lxml
答案 3 :(得分:14)
http://pyxb.sourceforge.net/处的PyXB包从XML模式文档生成Python的验证绑定。它几乎处理每个模式构造并支持多个名称空间。
答案 4 :(得分:8)
有两种方法(实际上还有更多)可以做到这一点
1.使用lxml
pip install lxml
from lxml import etree, objectify
from lxml.etree import XMLSyntaxError
def xml_validator(some_xml_string, xsd_file='/path/to/my_schema_file.xsd'):
try:
schema = etree.XMLSchema(file=xsd_file)
parser = objectify.makeparser(schema=schema)
objectify.fromstring(some_xml_string, parser)
print "YEAH!, my xml file has validated"
except XMLSyntaxError:
#handle exception here
print "Oh NO!, my xml file does not validate"
pass
xml_file = open('my_xml_file.xml', 'r')
xml_string = xml_file.read()
xml_file.close()
xml_validator(xml_string, '/path/to/my_schema_file.xsd')
>> xmllint --format --pretty 1 --load-trace --debug --schema /path/to/my_schema_file.xsd /path/to/my_xml_file.xml
答案 5 :(得分:7)
lxml提供了etree.DTD
来自http://lxml.de/api/lxml.tests.test_dtd-pysrc.html
的测试...
root = etree.XML(_bytes("<b/>"))
dtd = etree.DTD(BytesIO("<!ELEMENT b EMPTY>"))
self.assert_(dtd.validate(root))
答案 6 :(得分:4)
您可以使用xmlschema Python package根据XML Schema(XSD)轻松验证XML文件或树。它是纯Python,可在PyPi上使用,并且没有很多依赖项。
示例-验证文件:
import xmlschema
xmlschema.validate('doc.xml', 'some.xsd')
如果文件未针对XSD进行验证,则该方法将引发异常。然后,该异常包含一些违规细节。
如果要验证许多文件,则只需加载一次XSD:
xsd = xmlschema.XMLSchema('some.xsd')
for filename in filenames:
xsd.validate(filename)
如果您不需要例外,可以这样验证:
if xsd.is_valid('doc.xml'):
print('do something useful')
或者,xmlschema直接在文件对象和内存XML树中工作(使用xml.etree.ElementTree或lxml创建)。示例:
import xml.etree.ElementTree as ET
t = ET.parse('doc.xml')
result = xsd.is_valid(t)
print('Document is valid? {}'.format(result))
答案 7 :(得分:0)
import xmlschema
def get_validation_errors(xml_file, xsd_file):
schema = xmlschema.XMLSchema(xsd_file)
validation_error_iterator = schema.iter_errors(xml_file)
errors = list()
for idx, validation_error in enumerate(validation_error_iterator, start=1):
err = validation_error.__str__()
errors.append(err)
print(err)
return errors
errors = get_validation_errors('sample3.xml', 'sample_schema.xsd')