可以使用 lxml根据给定的 XSD 模式验证 XML 文件。
有没有办法在不太严格的意义上应用此验证,忽略所有包含特殊表达式的元素?
考虑以下示例:比如说,我有一个 xml_file:
<foo>99</foo>
<foo>{{var1}}</foo>
<foo>{{var2}}</foo>
<foo>999</foo>
现在,我在这个文件上运行一个程序,它替换了 {{...}} -表达式并生成一个新文件:
xml_file_new:
<foo>99</foo>
<foo>23</foo>
<foo>42</foo>
<foo>999</foo>
到目前为止,我可以使用 lxml按如下方式验证新的 XML 文件:
from lxml import etree
xml_root = etree.parse(xml_file_new)
xsd_root = etree.parse(xsd_file)
schema = etree.XMLSchema(xsd_root)
schema.validate(xml_root)
我示例中的相关点是模式限制了 <foo>内容到整数。
不可能在旧的 xml_file 上应用架构然而,在我的程序执行其他一些昂贵的任务之前,我想在忽略包含任何 {{...}} 的所有行的同时做到这一点。 -表达式:
<foo>99</foo> <!-- should be checked-->
<foo>{{var1}}</foo> <!-- should be ignored -->
<foo>{{var2}}</foo> <!-- should be ignored -->
<foo>999</foo> <!-- should be checked-->
编辑:可能的解决方法:一个想法是定义两个模式
- 新文件的严格第二模式,只允许整数
- 旧文件的宽松架构,允许使用
{{..}}的整数和任意字符串-表达式
但是,为了避免保持两个模式同步的冗余任务,需要一种方法来自动从严格模式生成宽松模式。这听起来很有前途,因为这两个模式具有相同的结构,仅在某些元素内容的限制方面有所不同。 XSD 是否提供了一个简单的概念,允许仅从一个模式“继承”,然后将额外的放宽“附加”到各个元素?
请您参考如下方法:
要回答编辑过的问题,可以使用 xs:include 组合模式(和 xs:import)机制。这样,您可以在公共(public)模式中声明公共(public)部分以供重用,并使用专用模式来进行专门的类型定义,如下所示:
描述结构的通用模式。 请注意,它使用了 FooType,但没有定义它:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Example structure -->
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="FooType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
替换前要验证的宽松 模式。 它包括来自通用模式的组件, 并定义了一个宽松的 FooType:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="common.xsd"/>
<xs:simpleType name="FooType">
<xs:union memberTypes="xs:integer">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="\{\{.*\}\}"/>
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
</xs:schema>
替换后要验证的严格 架构。它 定义了 FooType 的严格版本:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="common.xsd"/>
<xs:simpleType name="FooType">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:schema>
为了完成,还有其他方法可以做到这一点, 例如 xs:redefine (XSD 1.0) 或 xs:override (XSD 1.1)。 但它们具有更复杂的语义,我个人尽量避免使用它们。
