谁是对的,谁做了错误的验证(我、XMLSpy、lxml.etree 或 xmllint)

Who is right and who does the faulty validation (Me, XMLSpy, lxml.etree or xmllint)

我试图用同一文件夹中随后的 xsd 文件验证以下 XML。根据 Altova XMLSpy 的说法,这是完全有效的,但为了帮助一些没有许可证的同事找出基本错误,我尝试使用 python 和 'lxml.etree' 以及 xml棉绒。这两个说 xml 无效,消息相同:

machineDB.xml:20: Schemas validity error : Element 'canframe': No match found for key-sequence ['remotebus'] of keyref 'busRef'. machineDB.xml fails to validate

有人可以帮忙找谁的错吗?


版本:

Altova XMLSpy Professional Edition version 2016 rel. 2 sp1 (x64)

lxml.etree 个版本

Python : sys.version_info(major=2, minor=7, micro=11, releaselevel='final', serial=0) lxml.etree : (3, 7, 2, 0) libxml used : (2, 9, 4) libxml compiled : (2, 9, 4) libxslt used : (1, 1, 29) libxslt compiled : (1, 1, 29)

xmllint(使用 libxml 版本 20708)

machineDB.xml 文件:

<machinedb xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="machinedb.xsd">
    <busdefinition>
        <bus name="displaybus"></bus>
        <bus name="remotebus"></bus>
    </busdefinition>
    <cdefinition>
        <c>
            <canbus bus_ref="remotebus"></canbus>
            <canbus bus_ref="displaybus"></canbus>
        </c>
        <c>
            <canbus bus_ref="displaybus"></canbus>
        </c>
        <c>
            <canbus bus_ref="remotebus"></canbus>
        </c>
    </cdefinition>
    <sdefinition>
        <s>
            <canframe bus_ref="remotebus"></canframe>
        </s>
    </sdefinition>
</machinedb>

machinedb.xsd 文件:

<xs:schema xmlns:altova="http://www.altova.com/xml-schema-extensions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified" attributeFormDefault="unqualified" vc:minVersion="1.1">
    <xs:element name="machinedb">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="busdefinition" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="bus" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:attribute name="name" type="NameType" use="required"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="cdefinition" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="c" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:sequence minOccurs="0" maxOccurs="unbounded">
                                        <xs:choice>
                                            <xs:element name="canbus" minOccurs="0" maxOccurs="unbounded">
                                                <xs:complexType>
                                                    <xs:attribute name="bus_ref" type="NameType" use="required"/>
                                                </xs:complexType>
                                            </xs:element>
                                        </xs:choice>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="sdefinition" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="s" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:sequence minOccurs="0" maxOccurs="unbounded">
                                        <xs:choice>
                                            <xs:element name="canframe" minOccurs="0" maxOccurs="unbounded">
                                                <xs:complexType>
                                                    <xs:attribute name="bus_ref" use="required"/>
                                                </xs:complexType>
                                            </xs:element>
                                        </xs:choice>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="busKey">
            <xs:selector xpath="busdefinition/bus"/>
            <xs:field xpath="@name"/>
        </xs:key>
        <xs:keyref name="busRef" refer="busKey">
            <xs:selector xpath="cdefinition/c/canbus |sdefinition/s/canframe"/>
            <xs:field xpath="@bus_ref"/>
        </xs:keyref>
    </xs:element>
    <xs:simpleType name="NameType">
        <xs:restriction base="xs:string">
            <xs:pattern value="[\w_]+"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

有趣的问题。如果在没有自定义限制的情况下将 bus_refcanbustype 设置为 xs:string,问题就会消失(参见 this question):

<xs:attribute name="bus_ref" type="xs:string" use="required"/>
<!--...-->
<xs:attribute name="bus_ref" use="required" type="xs:string"/>

认为(胡乱猜测)这是使用 libxml 的工具的一个特定缺点,Xerces 和 Saxon 的行为是正确的。

架构包含属性

vc:minVersion="1.1"

这表明它是一个 XSD 1.1 架构。用 Liquid XML 验证它我得到以下结果

使用 .Net Validating reader 它报告它是有效的。 .Net 解析器是一个 XSD 1.0 解析器并且不知道 vc:minVersion 属性所以只是忽略它,将其视为 1.0 模式.

在 XSD 1.0 模式下使用 .Xerces Validating 验证失败。 Xerces 知道 vc:minVersion 属性并且 所以忽略模式 因为它不在 1.1 模式下。

使用 .Xerces 在 XSD 1.1 模式下验证 它验证 。 Xerces 知道 vc:minVersion 并且可以使用 XSD 1.1 标准进行验证并认为一切正常。

其他不支持 XSD 1.1 的解析器可以采用任何一种方式。

顺便说一句,我不认为该架构包含任何特定于 1.1 的内容(语法上或功能上),所以我不确定为什么它被标记为 1.1 架构。

但是回到你得到的错误,我认为这是你使用的解析器的一个怪癖。