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

Mar*_*cin 5 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

有没有一种方法可以使用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
Run Code Online (Sandbox Code Playgroud)

因为所讨论的文档包含一个{http://xmlgw.companieshouse.gov.uk}CompanyIncorporation元素,该元素未在要验证的XSD中指定,而是在其他XSD文件之一中指定。

Fra*_*ila 5

我相信您应该只针对进行验证Egov_ch-v2-0.xsd,后者似乎定义了信封文档。(这是您正在创建的文档,对吗?您没有显示XML。)

此架构用于<xs:any namespace="##any" minOccurs="0"/>定义信封的正文内容。然而,xsd:any并不是意味着“忽略所有内容。” 而是表示“在这里接受任何内容”。验证还是忽略内容由processContents属性控制,该属性默认为strict。这意味着在这里发现的任何元素都必须针对模式可用的类型进行验证。但是,Egov_ch-v2-0.xsd由于不会导入CompanyIncorporation-v1-2.xsd,因此它不知道该CompanyIncorporation元素,因此该文档不会生效。

您需要xsd:import在主模式(Egov_ch-v2-0.xsd)中添加元素,以导入文档中可能使用的所有其他模式。您可以在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)
Run Code Online (Sandbox Code Playgroud)

你甚至可以做这与采用的模式路径列表,返回列表的功能的通用方法xsd:import与报表namespaceschemaLocation通过解析集targetNamespace

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