Проверка с помощью XML-схемы в Python

У меня есть XML файл и XML-схема в другом файле, и я хотел бы подтвердить, что мой XML файл придерживается схемы. Как это сделать в Python?

Я бы предпочел что-то, используя стандартную библиотеку, но при необходимости я могу установить сторонний пакет.

Ответ 1

Я предполагаю, что вы имеете в виду использование XSD файлов. Удивительно, что не так много библиотек XML python, которые поддерживают это. Однако lxml. Проверьте Проверка с помощью lxml. На странице также перечислены способы использования lxml для проверки с помощью других типов схем.

Ответ 2

Что касается решений "чистого питона": списки индексов пакетов:

  • pyxsd, в описании говорится, что он использует xml.etree.cElementTree, который не является "чистым python" (но включен в stdlib), но исходный код указывает что он возвращается к xml.etree.ElementTree, поэтому это будет считаться чистым питоном. Не использовали его, но, согласно документам, он выполняет проверку схемы.
  • minixsv: "легкий валидатор XML-схем, написанный на" чистом "Python. Однако в описании указано, что" в настоящее время поддерживается подмножество стандарта XML-схемы", поэтому этого может быть недостаточно.
  • XSV, который, как мне кажется, используется для проверки подлинности W3C онлайн xsd (он все еще, кажется, использует старый пакет pyxml, который, как мне кажется, больше не поддерживается )

Ответ 3

Пакет PyXB в http://pyxb.sourceforge.net/ генерирует проверку привязок для Python из документов схемы XML. Он обрабатывает почти каждую конструкцию схемы и поддерживает несколько пространств имен.

Ответ 5

Есть два способа (на самом деле есть больше), чтобы вы могли это сделать.
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')
  1. Используйте xmllint из командной строки. xmllint устанавливается во многих дистрибутивах Linux.

>> xmllint --format --pretty 1 --load-trace --debug --schema /path/to/my_schema_file.xsd /path/to/my_xml_file.xml

Ответ 6

Пример простого валидатора в Python3 с использованием популярной библиотеки lxml

Установка lxml

pip install lxml

Если вы получили сообщение об ошибке "Не удалось найти функцию xmlCheckVersion в библиотеке libxml2. Установлен ли 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

Ответ 7

Если вы работаете с dtd, вам может понравиться этот recipe