2010-07-25 9 views
5

hohe Prämie für die folgende Frage:Wie validiere ich eine XML-Datei gegen ein XSD-Schema mit der Amara-Bibliothek in Python?

Hallo, Hier ist, was ich auf Ubuntu 9.10 mit Python versucht, 2.6, Amara2 (übrigens, Test.xsd wurde mit xml2xsd Tool erstellt):

[email protected]:~$ cat test.xml; echo =====o=====; cat test.xsd; echo ==== 
o=====; cat test.py; echo =====o=====; ./test.py; echo =====o===== 
<?xml version="1.0" encoding="utf-8"?>==; ./test.py` > 
test.txttest.xsd; echo === 
<test>abcde</test> 
=====o===== 
<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
elementFormDefault="qualified"> 
    <xs:element name="test" type="xs:NCName"/> 
</xs:schema> 
=====o===== 
#!/usr/bin/python2.6 
# I wish to validate an xml file against an external XSD schema. 
from amara import bindery, parse 
source = 'test.xml' 
schema = 'test.xsd' 
#help(bindery.parse) 
#doc = bindery.parse(source, uri=schema, validate=True) # These 2 seem 
to fail in the same way. 
doc = parse(source, uri=schema, validate=True) # So, what is the 
difference anyway? 
# 
=====o===== 
Traceback (most recent call last): 
    File "./test.py", line 14, in <module> 
    doc = parse(source, uri=schema, validate=True) 
    File "/usr/local/lib/python2.6/dist-packages/Amara-2.0a4-py2.6-linux- 
x86_64.egg/amara/tree.py", line 50, in parse 
    return _parse(inputsource(obj, uri), flags, 
entity_factory=entity_factory) 
amara.ReaderError: In file:///home/g/test.xml, line 2, column 0: 
Missing document type declaration 
[email protected]:~$ 
=====o===== 

Also, warum sehe ich diesen Fehler? Wird diese Funktionalität nicht unterstützt? Wie kann ich eine XML-Datei für eine XSD validieren, während die Flexibilität auf eine XSD-Datei verweist? Danke, und lassen Sie mich wissen, wenn Sie Fragen haben.

+0

Möchten Sie Amara Library verwenden? –

+0

@movieyoda, nein, ich kann zu einer anderen guten Python XML-Bibliothek springen. Allerdings müsste ich dann meinen bestehenden 'Amara'-Code dorthin portieren, und ich hoffe, dass ich dafür eine schmerzlose Lösung finde. –

Antwort

5

Wenn Sie eine andere Bibliothek außer Amara verwenden möchten, versuchen Sie lxml. Es unterstützt, was Sie versuchen ziemlich einfach zu tun:

from lxml import etree 

source_file = 'test.xml' 
schema_file = 'test.xsd' 

with open(schema_file) as f_schema: 

    schema_doc = etree.parse(f_schema) 
    schema = etree.XMLSchema(schema_doc) 
    parser = etree.XMLParser(schema = schema) 

    with open(source_file) as f_source: 
     try: 
      doc = etree.parse(f_source, parser) 
     except etree.XMLSyntaxError as e: 
      # this exception is thrown on schema validation error 
      print e 
+0

Danke, ich könnte umschalten - amara, wie es ist, ist eine Hektik. Wie kann ich etwas Ähnliches tun wie 'für q in doc.quotes.quote: # Die Schleife wird beide q Elemente' von http://wiki.xml3k.org/Amara2/Tutorial aufnehmen? Ich wurde anfangs mit der Auto-Bindung verkauft, weil es angeblich der Python-Weg ist. Aber mein Unbehagen mit Amara wächst ... –

+0

Das ist eine andere Frage als das Original. (Aber die Art und Weise, wie ich es machen würde, ist mit xpath ... 'für q in doc.xpath ('quotes/quote'): ...') Mit lxml kannst du so ziemlich jedes xml/xsl/xpath/xsd machen Aufgabe, die Sie brauchen würden. – snapshoe

1

ich Sie noNamespaceSchemaLocation Attribut zu binden, um die XML-Datei in das XSD-Schema zu verwenden, werden empfohlen. Dann wird die XML-Datei test.xml

<?xml version="1.0" encoding="utf-8"?> 
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:noNamespaceSchemaLocation="test.xsd">abcde</test> 

sein, wo die Datei Test.xsd

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      elementFormDefault="qualified"> 
    <xs:element name="test" type="xs:NCName"/> 
</xs:schema> 

sollte im selben Verzeichnis wie die Test.xsd platziert werden. Es ist allgemeine Technik, das XML-Schema aus der XML-Datei zu referenzieren, und es sollte in Python funktionieren. Der Vorteil ist, dass Sie die Schemadatei für jede XML-Datei nicht kennen müssen. Es wird automatisch beim Parsen (etree.parse) der XML-Datei gefunden.

+0

Aber er will die Flexibilität, auf irgendeine XSD zu verweisen, nicht nur auf die in der XML-Datei angegebene (falls vorhanden). – snapshoe

+0

@ ma3204: Wenn jemand ein XML-Dokument schreibt, schreibt er es einem Schema. Sie sollten nicht versuchen, das Dokument in einem anderen Schema zu interpretieren. XML ist eine Metasprache. XSD definiert eine bestimmte Sprache. Wenn Sie einen Text in einer Sprache geschrieben haben, die Sie nicht interpretieren sollten, dann ist das ein Text in einer anderen Sprache. Daher kann nur die Person **, die ** ein XML-Dokument schreibt, den XSD dafür angeben. – Oleg

+0

Ich habe uploated, aber mein Anwendungsfall ist anders. Der Xml wird täglich automatisch generiert (zum Testen), aber das Schema ist genau festgelegt, weil der automatische Generator Fehler machen kann. –

Verwandte Themen