我在另一个文件中有一个XML文件和一个XML模式,我想验证我的XML文件是否符合模式.我如何在Python中执行此操作?
我更喜欢使用标准库的东西,但如果需要,我可以安装第三方软件包.
我假设你的意思是使用XSD文件.令人惊讶的是,支持这一点的python XML库并不多.然而,lxml确实如此.使用lxml检查验证.该页面还列出了如何使用lxml来验证其他模式类型.
至于"纯python"解决方案:包索引列表:
pyxsd,描述说它使用xml.etree.cElementTree,它不是"纯python"(但包含在stdlib中),但源代码表明它回退到xml.etree.ElementTree,所以这将算作纯python.没有使用它,但根据文档,它确实进行模式验证.
minixsv:'用"纯"Python编写的轻量级XML模式验证器.但是,描述说"当前支持XML模式标准的子集",因此这可能还不够.
XSV,我认为它用于W3C的在线xsd验证器(它似乎仍然使用旧的pyxml包,我认为不再维护)
安装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! :(')
有关更多选项,请阅读此处:使用lxml进行验证
http://pyxb.sourceforge.net/上的PyXB包从XML模式文档生成Python的验证绑定.它几乎处理每个模式构造并支持多个名称空间.
有两种方法(实际上还有更多)你可以做到这一点.
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.xmllint安装在许多Linux发行版中.
>> xmllint --format --pretty 1 --load-trace --debug --schema /path/to/my_schema_file.xsd /path/to/my_xml_file.xml
lxml提供了etree.DTD
来自http://lxml.de/api/lxml.tests.test_dtd-pysrc.html上的测试
... root = etree.XML(_bytes("")) dtd = etree.DTD(BytesIO("")) self.assert_(dtd.validate(root))
您可以使用xmlschema Python软件包轻松针对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))