Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用XML模式进行验证_Python_Xml_Validation_Xsd - Fatal编程技术网

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

在Python中使用XML模式进行验证,python,xml,validation,xsd,Python,Xml,Validation,Xsd,我在另一个文件中有一个XML文件和一个XML模式,我想验证我的XML文件是否符合该模式。如何在Python中实现这一点 我更喜欢使用标准库,但如有必要,我可以安装第三方软件包。lxml提供了etree.DTD 从测试开始 。。。 root=etree.XML(_字节(“”) dtd=etree.dtd(BytesIO(“”) self.assert(dtd.validate(root)) 我想你指的是使用XSD文件。令人惊讶的是,支持这一点的python XML库并不多。然而,lxml确实如此。

我在另一个文件中有一个XML文件和一个XML模式,我想验证我的XML文件是否符合该模式。如何在Python中实现这一点


我更喜欢使用标准库,但如有必要,我可以安装第三方软件包。

lxml提供了etree.DTD

从测试开始

。。。
root=etree.XML(_字节(“”)
dtd=etree.dtd(BytesIO(“”)
self.assert(dtd.validate(root))

我想你指的是使用XSD文件。令人惊讶的是,支持这一点的python XML库并不多。然而,lxml确实如此。检查。该页面还列出了如何使用lxml验证其他模式类型。

的PyXB包从XML模式文档生成Python的验证绑定。它处理几乎每一个架构构造并支持多个名称空间。

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

  • ,说明中说它使用的是xml.etree.cElementTree,它不是“纯python”(但包含在stdlib中),但源代码表明它返回到xml.etree.ElementTree,因此这将被视为纯python。没有使用它,但根据文档,它确实进行模式验证
  • :'一个用“纯”Python编写的轻量级XML模式验证器'。但是,描述中说“目前支持XML模式标准的一个子集”,因此这可能还不够
  • ,我认为它用于W3C的在线xsd验证器(它似乎仍然使用旧的pyxml包,我认为它不再维护)
    • 有两种方法(实际上还有更多)可以做到这一点。
      1.使用
      pip安装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安装在许多linux发行版中
    • >xmllint--format--pretty 1--load trace--debug--schema/path/to/my_schema_file.xsd/path/to/my_xml_file.xml

      Python3中使用流行库的简单验证器示例 安装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
      
      from validator import validate
      
      if validate("path/to/file.xml", "path/to/scheme.xsd"):
          print('Valid! :)')
      else:
          print('Not valid! :(')
      
      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
      
      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! :(')
      
      然后写入并运行main.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
      
      from validator import validate
      
      if validate("path/to/file.xml", "path/to/scheme.xsd"):
          print('Valid! :)')
      else:
          print('Not valid! :(')
      
      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
      
      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! :(')
      

      一点OOP

      为了验证多个文件,无需每次都创建XMLSchema对象,因此:

      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
      
      from validator import validate
      
      if validate("path/to/file.xml", "path/to/scheme.xsd"):
          print('Valid! :)')
      else:
          print('Not valid! :(')
      
      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
      
      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! :(')
      
      现在,我们可以验证目录中的所有文件,如下所示:

      main.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
      
      from validator import validate
      
      if validate("path/to/file.xml", "path/to/scheme.xsd"):
          print('Valid! :)')
      else:
          print('Not valid! :(')
      
      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
      
      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! :(')
      


      要了解更多选项,请阅读此处:

      您可以使用根据XML模式(XSD)轻松验证XML文件或树。它是纯Python,在上可用,没有太多依赖项

      示例-验证文件:

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

      lxml是否是纯python?(确实需要编译/安装,或者您可以将其包含在python脚本中)@Sorin:lxml是libxml2 C库顶部的包装器,因此不是纯python。@eli正是我想要强调的,这可能不适合任何人。验证错误对用户不友好。我该怎么做呢?没用。这个答案仍然是最新的吗?我会在上面看看PyXB。看起来这些状态中的大多数都是不完整的,看起来有些“死了”。据我所知,pyxsd上次更新是在2006年,minixsv上次更新是在2008年,XSV是在2007年。不总是最好的理由来考虑一个包超过另一个,但我认为在这种情况下是合理的。+ 1的PYXB。我在Django中使用它来验证插入到管理部分的原始XML。简单易用。我有3个xsd文件,只有当所有3个xsd都存在时,我才能验证xml…这可以用你的方法完成吗?