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

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

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

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
109
0
111 392
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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)) 
Ответ принят как подходящий

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

lxml - чистый питон или нет? (требует компиляции / установки или вы можете просто включить его в свои скрипты python)

sorin 14.06.2010 18:08

@Sorin: lxml - это оболочка поверх библиотеки libxml2 C и, следовательно, не чистый Python.

Eli Courtwright 07.07.2010 16:18

@eli Именно то, что я хотел подчеркнуть, это может никому не подойти.

sorin 08.07.2010 23:48

Ошибки проверки не удобны для пользователя. Как мне это сделать? mailman-mail5.webfaction.com/pipermail/lxml/2012-April/… не помогает.

None-da 24.05.2012 15:27

Этот ответ все еще актуален?

Human 22.04.2020 13:53

Да, вы все еще можете использовать lxml. С тех пор кажется, что был создан pypi.org/project/xmlschema, который выглядит как хорошая альтернатива чистому питону (я сам не использовал его).

Keegan Carruthers-Smith 23.04.2020 16:19

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

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

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

Я бы посмотрел на PyXB поверх них. Похоже, что в большинстве случаев они являются неполными и кажутся несколько «мертвыми». Насколько я могу судить, pyxsd последний раз обновлялся в 2006 году, minixsv последний раз обновлялся в 2008 году, XSV - в 2007 году. Не всегда лучший повод отдавать предпочтение одному пакету, но я думаю, что в данном случае он оправдан.

oob 31.12.2011 06:40

+1 для PyXB. Я использую его в Django для проверки необработанного XML, вставленного в раздел администратора. Легко и просто использовать.

tatlar 04.04.2013 03:21

Есть два способа (на самом деле их больше), чтобы вы могли это сделать. 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

У меня есть 3 файла xsd, только когда присутствуют все 3 файла xsd, я могу проверить xml ... можно ли это сделать с помощью вашего метода?

Naveen 24.01.2019 20:31

Пример простого валидатора на 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

Вы можете легко проверить XML-файл или дерево на соответствие XML-схеме (XSD) с помощью xmlschema пакет Python. Это чистый 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))

Другие вопросы по теме