【问题标题】:Validate with three xml schemas as one combined schema in lxml?使用三个 xml 模式作为 lxml 中的一个组合模式进行验证?
【发布时间】:2012-03-20 09:37:12
【问题描述】:

我正在生成一个 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

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

【问题讨论】:

  • 您确定不想针对 不同 模式而不是 all验证 XML 文档的 部分 > 针对相同文档的模式?
  • 我确定我想检查合并的文档是否有效。

标签: python xml xsd lxml


【解决方案1】:

我认为您应该只针对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)

您甚至可以通过一个函数以通用方式执行此操作,该函数采用架构路径列表并返回 xsd:import 语句列表,其中 namespaceschemaLocation 通过解析 targetNamespace 设置。

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

【讨论】:

  • 谢谢。提出这个问题的原因是这根本行不通,因为验证器在遇到生成它的 XSD 文档中未指定的元素时会返回无效的判断。我需要某种方法来创建组合验证器,以了解所有三个 XSD 文件中的信息。我意识到那个问题的细节不在我原来的问题中。
  • 那么文档对该架构无效。是什么让你认为它应该是有效的? XSD 和 XML 文档不能任意组合在一起。
  • 让我认为它应该有效的是被投诉的元素显示为一个元素的内容,其内容被指定为<xs:any namespace="##any" minOccurs="0"/>
  • 查看更新的答案。您需要将 xsd:import 语句添加到您的主架构中。
  • 不错!谢谢!这里也是解释:stackoverflow.com/questions/38910347/…
猜你喜欢
  • 2011-03-10
  • 1970-01-01
  • 2016-12-19
  • 2015-10-19
  • 2013-07-21
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
相关资源
最近更新 更多