代码之家  ›  专栏  ›  技术社区  ›  Hamish Grubijan

如何使用Python中的Amara库根据XSD模式验证XML文件?

  •  5
  • Hamish Grubijan  · 技术社区  · 15 年前

    对以下问题给予高度奖励:

    你好, 下面是我在Ubuntu9.10上使用python 2.6,amara2所做的尝试 (顺便说一下,test.xsd是使用xml2xsd工具创建的):

    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===== 
    

    那么,为什么我会看到这个错误?是否不支持此功能? 如何在具有 指向任何XSD文件的灵活性? 谢谢,如果有问题请告诉我。

    2 回复  |  直到 15 年前
        1
  •  5
  •   snapshoe    15 年前

    如果你愿意使用阿马拉以外的其他图书馆,试试看。 lxml . 它可以很容易地支持您想要做的事情:

    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
    
        2
  •  1
  •   Oleg    15 年前

    我建议你用 noNamespaceSchemaLocation 属性将XML文件绑定到XSD架构。那么您的xml文件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>
    

    其中,文件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>
    

    应该与test.xsd放在同一个目录中。从XML文件引用XML模式是一种通用技术,它应该在Python中工作。

    优势是你 不需要知道每个XML文件的架构文件 . 它将在解析过程中自动找到( etree.parse )XML文件的。

    推荐文章