PythonでのXMLスキーマによる検証


104

XMLファイルとXMLスキーマが別のファイルにあり、XMLファイルがスキーマに準拠していることを検証したい。Pythonでこれを行うにはどうすればよいですか?

標準ライブラリを使用したいのですが、必要に応じてサードパーティのパッケージをインストールできます。

回答:


61

私はあなたがXSDファイルを使用することを意味すると仮定しています。驚いたことに、これをサポートするpython XMLライブラリは多くありません。ただし、lxmlにはあります。チェックlxmlのと検証を。このページには、lxmlを使用して他のスキーマタイプで検証する方法もリストされています。


1
lxmlは純粋なpythonですか?(コンパイル/インストールが必要ですか、それともPythonスクリプトに含めることができます)
sorin

9
@ソリン:lxmlはlibxml2 Cライブラリのラッパーであるため、純粋なPythonではありません。
Eli Courtwright、2010

2
@eli下線を引いたかったとおり、これは誰にとっても適切ではないかもしれません。
ソリン2010

1
検証エラーはユーザーフレンドリーではありません。どうすればいいですか?mailman-mail5.webfaction.com/pipermail/lxml/2012-April/…役に立ちません。
なし。

この回答はまだ最新ですか?
人間

27

「純粋なpython」ソリューションの場合:パッケージインデックスのリスト:

  • pyxsd、説明ではxml.etree.cElementTreeを使用していると説明していますが、これは「純粋なpython」ではありませんが(stdlibに含まれています)、ソースコードはそれがxml.etree.ElementTreeにフォールバックすることを示しているため、これは純粋なpythonとしてカウントされます。使用していませんが、ドキュメントによると、スキーマの検証は行います。
  • minixsv: '「純粋な」Pythonで書かれた軽量のXMLスキーマ検証ツール '。ただし、「現在、XMLスキーマ標準のサブセットがサポートされている」と説明されているため、これでは不十分な場合があります。
  • XSVは、W3Cのオンラインxsdバリデーターに使用されていると思います(まだ古いpyxmlパッケージを使用しているようですが、これはもう保守されていないと思います)。

5
これらについてPyXBを見てみましょう。これらの状態のほとんどは不完全であり、いくぶん「死んでいる」ように見えます。私が知る限り、pyxsdは2006年に最後に更新され、minixsvは2008年に最後に更新され、XSVは2007年に更新されました。常にあるパッケージを別のパッケージと比較する最良の理由とは限りませんが、この場合は正当化されると思います。
oob

2
PyXBの場合は+1。Djangoで、Adminセクションに挿入された未加工のXMLを検証するために使用しています。シンプルで使いやすい。
tatlar 2013

21

人気のライブラリlxmlを使用したPython3の単純なバリデーターの例

インストールlxml

pip install lxml

「ライブラリlibxml2に関数xmlCheckVersionが見つかりませんでした。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による検証



12

これを行うには2つの方法があります(実際にはもっと多くの方法があります)。
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

xmlschema Pythonパッケージを使用すると、XMLスキーマ(XSD)に対してXMLファイルまたはツリーを簡単に検証できます。これは純粋な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))

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.