Проверка с помощью 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. Он обрабатывает почти каждую конструкцию схемы и поддерживает несколько пространств имен.
Ответ 4
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))
Ответ 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')
- Используйте 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