在Python中用XML架构进行验证

141 投票
8 回答
167720 浏览
提问于 2025-04-11 20:32

我有一个XML文件,还有一个在另一个文件里的XML模式(schema),我想检查一下我的XML文件是否符合这个模式。请问我该怎么在Python中做到这一点呢?

我希望能用标准库里的工具,但如果需要的话,我也可以安装第三方的包。

8 个回答

41

你可以很简单地用一个叫做 xmlschema 的 Python 包 来验证一个 XML 文件或树是否符合 XML 模式(XSD)。这个包是纯 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))
43

一个使用流行库 lxml 的简单验证器示例

安装 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! :(')

一点面向对象编程

为了验证多个文件,我们不需要每次都创建一个 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 进行验证

73

我猜你是指使用XSD文件。令人惊讶的是,支持这个的Python XML库并不多。不过,lxml库是可以的。你可以查看一下lxml的验证功能。这个页面还列出了如何用lxml来验证其他类型的模式。

撰写回答