我正在生成一个XML文档,为不同的部分提供了不同的XSD(也就是说,某些元素的定义在某些文件中,其他元素的定义在其他文件中)。
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
因为有问题的文档包含{http://xmlgw.companieshouse.gov.uk}CompanyIncorporation
元素,该元素未在XSD中指定,而是在其他XSD文件中进行验证。
答案 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
语句列表,其中schemaLocation
和targetNamespace
通过解析{{{1}}来设置1}}。
(顺便说一下,您应该下载这些架构文档并使用文件系统路径引用它们,而不是通过网络加载它们。)