在lxml中使用三个xml架构作为一个组合架构进行验证?

时间:2012-03-01 20:52:41

标签: python xml xsd lxml

我正在生成一个XML文档,为不同的部分提供了不同的XSD(也就是说,某些元素的定义在某些文件中,其他元素的定义在其他文件中)。

XSD文件不互相引用。架构是:

  1. http://xmlgw.companieshouse.gov.uk/v2-1/schema/Egov_ch-v2-0.xsd
  2. http://xmlgw.companieshouse.gov.uk/v1-1/schema/forms/FormSubmission-v1-1.xsd
  3. http://xmlgw.companieshouse.gov.uk/v1-1/schema/forms/CompanyIncorporation-v1-2.xsd
  4. 有没有办法使用lxml?

    针对所有模式验证文档

    这里的解决方案只是为了针对每个模式单独进行验证,因为我遇到的问题是验证因XSD中未指定的元素而失败。例如,在针对http://xmlgw.companieshouse.gov.uk/v2-1/schema/Egov_ch-v2-0.xsd进行验证时,我收到错误:

      File "lxml.etree.pyx", line 3006, in lxml.etree._Validator.assertValid (src/lxml/lxml.etree.c:125415)
    DocumentInvalid: Element '{http://xmlgw.companieshouse.gov.uk}CompanyIncorporation': No matching global element declaration available, but demanded by the strict wildcard., line 9
    

    因为有问题的文档包含{http://xmlgw.companieshouse.gov.uk}CompanyIncorporation元素,该元素未在XSD中指定,而是在其他XSD文件中进行验证。

1 个答案:

答案 0 :(得分:4)

我相信你应该只对Egov_ch-v2-0.xsd进行验证,<xs:any namespace="##any" minOccurs="0"/>似乎定义了一个信封文件。 (这是您正在创建的文档,对吧?您还没有展示过XML。)

此架构使用xsd:any来定义信封的正文内容。但是,processContents 表示“忽略所有内容”。相反它意味着“在这里接受任何东西”。是否验证或忽略内容由strict属性控制,默认为Egov_ch-v2-0.xsd。这意味着此处发现的任何元素必须验证模式可用的类型。但是,CompanyIncorporation-v1-2.xsd不会导入CompanyIncorporation,因此它不知道xsd:import元素,因此文档无法验证。

您需要将Egov_ch-v2-0.xsd元素添加到主模式(xsd = lxml.etree.parse('http://xmlgw.companieshouse.gov.uk/v2-1/schema/Egov_ch-v2-0.xsd') newimport = lxml.etree.Element('{http://www.w3.org/2001/XMLSchema}import', namespace="http://xmlgw.companieshouse.gov.uk", schemaLocation="http://xmlgw.companieshouse.gov.uk/v1-1/schema/forms/CompanyIncorporation-v1-2.xsd") xsd.getroot().append(newimport) validator = lxml.etree.XMLSchema(xsd) )以导入可能在文档中使用的所有其他模式。您可以在xsd文件本身中执行此操作,也可以在解析后以编程方式添加元素:

xsd:import

您甚至可以使用一个带有模式路径列表的函数以通用方式执行此操作,并返回namespace语句列表,其中schemaLocationtargetNamespace通过解析{{{1}}来设置1}}。

(顺便说一下,您应该下载这些架构文档并使用文件系统路径引用它们,而不是通过网络加载它们。)