Вопрос

High bounty for the following Q:

Hello, Here is what I tried on Ubuntu 9.10 using Python 2.6, Amara2 (by the way, test.xsd was created using xml2xsd tool):

g@spot:~$ 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 
g@spot:~$ 
=====o===== 

So, why am I seeing this error? Is this functionality not supported? How can I validate an XML file against an XSD while having the flexibility to point to any XSD file? Thanks, and let me know if you have questions.

Это было полезно?

Решение

If you're open to using another library besides amara, try lxml. It supports what you're trying to do pretty easily:

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

Другие советы

I'll recommend you to use noNamespaceSchemaLocation attribute to bind the XML file to the XSD schema. Then your XML file test.xml will be

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

where the file 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>

should be placed in the same directory as the test.xsd. It is general technique to reference the XML schema from the XML file and it should work in Python.

The advantage is that you don't need to know the schema file for every XML file. It will be automatically found during parsing (etree.parse) of the XML file.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top