Перевірка за допомогою XML-схеми в Python


104

У мене є файл XML та схема XML в іншому файлі, і я хотів би підтвердити, що мій файл XML відповідає схемі. Як це зробити в Python?

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

Відповіді:


61

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


1
lxml чистий пітон чи ні? (потрібна компіляція / установка, або ви можете просто включити її до своїх сценаріїв python)
sorin

9
@Sorin: lxml - обгортка зверху бібліотеки libxml2 C, ​​і тому не є чистим Python.
Eli Courtwright

2
@eli Саме те, що я хотів підкреслити, це може не підходити нікому.
sorin

1
Помилки перевірки не є зручними для користувачів. Як би я пішов про це? mailman-mail5.webfaction.com/pipermail/lxml/2012-April/… не допомагає.
Ні-да

Чи є ця відповідь актуальною?
Людина

27

Що стосується рішень "чистого пітона": індекс пакунків перелічує:

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

5
Я хотів би поглянути на PyXB над цим. Схоже, більшість із цих станів вони неповні, і вони здаються дещо "мертвими". pyxsd востаннє оновлений у 2006 році, minixsv востаннє оновлений у 2008 році, XSV у 2007 році, наскільки я можу сказати. Не завжди найкраща причина розглянути один пакет над іншим, але я вважаю, що це виправдано в цьому випадку.
oob

2
+1 для PyXB. Я використовую його в Django для перевірки необробленого XML, вставленого в розділі Адміністратор. Простий і простий у використанні.
tatlar

21

Приклад простого валідатора в 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! :(')

Трохи 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


14

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


12

Є два способи (насправді їх більше), що ви могли це зробити.
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

9

Ви можете легко перевірити 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))

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.