J'ai un fichier XML et un schéma XML dans un autre fichier et je voudrais valider que mon fichier XML adhère au schéma. Comment faire cela en Python?
Je préférerais utiliser la bibliothèque standard, mais je peux installer un paquet tiers si nécessaire.
Je suppose que vous voulez dire en utilisant des fichiers XSD. Étonnamment, il n’ya pas beaucoup de python bibliothèques XML qui supportent cela. Lxml le fait cependant. Check Validation avec lxml . La page explique également comment utiliser lxml pour valider avec d’autres types de schéma.
En ce qui concerne les solutions "python pur": l'index des packages répertorie:
Installation lxml
pip install lxml
Si vous obtenez une erreur du genre "Impossible de trouver la fonction xmlCheckVersion dans la bibliothèque libxml2. Libxml2 est-il installé?", essayez de le faire en premier:
# 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
Le validateur le plus simple
Créons le plus simple 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
puis écrivez et exécutez main.py
from validator import validate
if validate("path/to/file.xml", "path/to/scheme.xsd"):
print('Valid! :)')
else:
print('Not valid! :(')
Un peu de POO
Afin de valider plusieurs fichiers, il n'est pas nécessaire de créer un objet XMLSchema à chaque fois. Par conséquent:
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
Maintenant, nous pouvons valider tous les fichiers du répertoire comme suit:
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! :(')
Pour plus d'options, lisez ici: Validation with lxml
Le package PyXB sur http://pyxb.sourceforge.net/ génère des liaisons de validation pour Python à partir de documents de schéma XML. Il gère presque chaque construction de schéma et prend en charge plusieurs espaces de noms. .
Vous pouvez le faire de deux manières (en fait, il y en a plus).
1. en utilisant 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
lxml fournit etree.DTD
à partir des tests sur 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))
Vous pouvez facilement valider un fichier XML ou une arborescence XML contre un schéma XML (XSD) avec le package xmlschema Python) . C'est du pur Python, disponible sur PyPi et n'a pas beaucoup de dépendances.
Exemple - valider un fichier:
import xmlschema
xmlschema.validate('doc.xml', 'some.xsd')
La méthode déclenche une exception si le fichier n'est pas validé par rapport à XSD. Cette exception contient alors certains détails de violation.
Si vous souhaitez valider de nombreux fichiers, il vous suffit de charger le fichier XSD une fois:
xsd = xmlschema.XMLSchema('some.xsd')
for filename in filenames:
xsd.validate(filename)
Si vous n'avez pas besoin de l'exception, vous pouvez valider comme ceci:
if xsd.is_valid('doc.xml'):
print('do something useful')
Sinon, xmlschema fonctionne directement sur les objets de fichier et dans les arborescences XML en mémoire (créées avec xml.etree.ElementTree ou lxml). Exemple:
import xml.etree.ElementTree as ET
t = ET.parse('doc.xml')
result = xsd.is_valid(t)
print('Document is valid? {}'.format(result))