如何跳过验证 lxml 中的全局声明问题?

How do I skip validating global declaration issues in lxml?

如何跳过 Element 'baz': No matching global declaration available for the validation root., line 1 这个错误?

我需要验证一组通用的 XML/XSD 对,它们不一定以任何方式相似地组成,因此适用于特定 XML 结构的 hardcoded/literal 规则不适用.

XSD 由 GMC Inspire Designer 生成,它通常不是 XML 验证器,并且在检查语法方面非常“松散”。全局声明问题出现在我的本地验证器中,但由于其松散的性质而不会出现在 Inspire Designer 中。

如何指定 lxml 将产生的特定错误集并继续验证?

使用以下代码:

#get a list of all files in the working directory that are .xml files
xml_files_from_cwd = [xml_f for xml_f in listdir(my_path) if isfile(join(my_path, xml_f)) 
                      and xml_f.lower().endswith(".xml")]

xml_validator = etree.XMLSchema(file= my_path)

for xml in xml_files_from_cwd:
    recovering_parser = etree.XMLParser(recover=True)
    xml_file = etree.parse(my_path + "/" +xml, parser=recovering_parser)

    successful = False 
    try:
        successful = xml_validator.assertValid(xml_file)
    except Exception as e:
        print(f"File not valid: {e}")
    
    if successful:
        print(f"No errors detected in {xml}.")

我在验证 XML 文件时遇到问题,其中 XML 看起来像这样:

<baz>
  <bar BEGIN="1">
  ... [repeating elements here]
  </bar>
</baz>

和一个遵循这种格式的 XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="foo">
    <xsd:complexType>
      <xsd:sequence minOccurs="1" maxOccurs="1">
        <xsd:element name="bar" minOccurs="1" maxOccurs="unbounded">
                  .... [repeating elements here]
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

这个问题“我们能否继续验证超过初始失败条件的文件”这个问题的答案似乎是否定的,因为无法保证任何进一步的验证是否会产生超过 [=12= 的积极结果] 例。

这里的问题是验证依赖于整个文档的有效性。

例如,如果您的文件适用于:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="foo">
    <xs:complexType>
       <xs:choice>
         <xs:element name="bar">
            <xs:complexType>
                <xs:choice>
                    <xs:element name="baz"/>
                    <xs:element name="qux"/>
                </xs:choice>
            </xs:complexType>
         </xs:element>
         <xs:element name="quux">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="qux"/>
                </xs:sequence>
            </xs:complexType>
         </xs:element>
       </xs:choice>    
    </xs:complexType>
  </xs:element>
</xs:schema>

这个文件会有问题:

<foo>
  <quuz>
    <qux/>
    ...
  </quuz>
</foo>

quuz 应该是 bar 还是 quux

您可能可以从接下来的内容中看出,但是每次您 运行 遇到问题时都必须回溯到每个决定,然后在那个时候尝试另一个决定。

这很快就会变得非常复杂,因为某些东西是否有效可能取决于它的内容、结构、属性值等。很快,您将有太多的选项来测试它变得不可能 - 您甚至可以考虑一下选择数量几乎是无限的情况,因此您必须包含非常复杂的逻辑才能得出有效值。

在简单的情况下,例如您展示的示例中只有外部标记可能被错误命名,您可以简单地修复内存中的错误并重试验证。但这不是扩展到整个文档的方法。

注意:在现实生活场景中,您可能实际上知道并期望会发生什么,您可以遵循尝试验证的策略,如果失败,请反复解决问题,因为您 do 知道选项是什么,直到到达文档末尾。我的回答只是想指出这里没有通用的解决方案。