У мене є файл XML та схема XML в іншому файлі, і я хотів би підтвердити, що мій файл XML відповідає схемі. Як це зробити в Python?
Я вважаю за краще щось використовувати стандартну бібліотеку, але при необхідності можу встановити сторонній пакет.
У мене є файл XML та схема XML в іншому файлі, і я хотів би підтвердити, що мій файл XML відповідає схемі. Як це зробити в Python?
Я вважаю за краще щось використовувати стандартну бібліотеку, але при необхідності можу встановити сторонній пакет.
Відповіді:
Я припускаю, що ви маєте на увазі використання файлів XSD. Дивно, але не так багато бібліотек python XML, які підтримують це. lxml, однак, робить. Перевірте перевірку за допомогою lxml . На сторінці також вказано, як використовувати 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! :(')
Трохи OOP
Щоб перевірити більше одного файлу, не потрібно кожного разу створювати об’єкт 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
Пакет PyXB за адресою http://pyxb.sourceforge.net/ генерує перевірку прив'язки для Python з документів схеми XML. Він обробляє майже кожну конструкцію схеми та підтримує кілька просторів імен.
Є два способи (насправді їх більше), що ви могли це зробити.
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 --format --pretty 1 --load-trace --debug --schema /path/to/my_schema_file.xsd /path/to/my_xml_file.xml
Ви можете легко перевірити 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 надає 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))