首页 文章

在Python中使用XML模式进行验证

提问于
浏览
85

我在另一个文件中有一个XML文件和一个XML模式,我想验证我的XML文件是否符合模式 . 我如何在Python中执行此操作?

我更喜欢使用标准库的东西,但如果需要,我可以安装第三方软件包 .

7 回答

  • 51

    http://pyxb.sourceforge.net/处的PyXB包从XML模式文档生成Python的验证绑定 . 它几乎处理每个模式构造并支持多个名称空间 .

  • 13

    使用流行的库lxml在Python3中使用简单验证器的示例

    Installation lxml

    pip install lxml
    

    如果您收到类似"Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?"的错误,请先尝试执行此操作:

    # 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
    

    The simplest validator

    让我们创造最简单的 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! :(')
    

    A little bit of 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

  • 8

    至于“纯python”解决方案:包索引列表:

    • pyxsd,描述说它使用xml.etree.cElementTree,它不是"pure python"(但包含在stdlib中),但源代码表明它回退到xml.etree.ElementTree,所以这将算作纯python . 没有使用它,但根据文档,它确实进行了模式验证 .

    • minixsv:'a lightweight XML schema validator written in 371178 Python' . 但是,描述说"currently a subset of the XML schema standard is supported",所以这可能还不够 .

    • XSV,我认为它用于W3C的在线xsd验证器(它似乎仍然使用旧的pyxml包,我认为不再维护)

  • 1

    有两种方法(实际上还有更多)你可以做到这一点 .
    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

  • 22

    我假设你的意思是使用XSD文件 . 令人惊讶的是,没有很多python XML库支持这一点 . 然而,lxml确实如此 . 检查Validation with lxml . 该页面还列出了如何使用lxml来验证其他模式类型 .

  • 11

    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))
    
  • 7

    您可以使用xmlschema Python package轻松地针对XML架构(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))
    

相关问题