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






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 для проверки с другими типами схем.
@Sorin: lxml - это оболочка поверх библиотеки libxml2 C и, следовательно, не чистый Python.
@eli Именно то, что я хотел подчеркнуть, это может никому не подойти.
Ошибки проверки не удобны для пользователя. Как мне это сделать? mailman-mail5.webfaction.com/pipermail/lxml/2012-April/… не помогает.
Этот ответ все еще актуален?
Да, вы все еще можете использовать lxml. С тех пор кажется, что был создан pypi.org/project/xmlschema, который выглядит как хорошая альтернатива чистому питону (я сам не использовал его).
Пакет PyXB по адресу http://pyxb.sourceforge.net/ генерирует проверочные привязки для Python из документов схемы XML. Он обрабатывает почти все конструкции схемы и поддерживает несколько пространств имен.
Что касается решений "чистого питона": в индексе пакетов перечислены:
Я бы посмотрел на PyXB поверх них. Похоже, что в большинстве случаев они являются неполными и кажутся несколько «мертвыми». Насколько я могу судить, pyxsd последний раз обновлялся в 2006 году, minixsv последний раз обновлялся в 2008 году, XSV - в 2007 году. Не всегда лучший повод отдавать предпочтение одному пакету, но я думаю, что в данном случае он оправдан.
+1 для PyXB. Я использую его в Django для проверки необработанного XML, вставленного в раздел администратора. Легко и просто использовать.
Есть два способа (на самом деле их больше), чтобы вы могли это сделать.
1. используя lxmlpip 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 --format --pretty 1 --load-trace --debug --schema /path/to/my_schema_file.xsd /path/to/my_xml_file.xml
У меня есть 3 файла xsd, только когда присутствуют все 3 файла xsd, я могу проверить xml ... можно ли это сделать с помощью вашего метода?
Установка 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))
lxml - чистый питон или нет? (требует компиляции / установки или вы можете просто включить его в свои скрипты python)