【问题标题】:Who is right and who does the faulty validation (Me, XMLSpy, lxml.etree or xmllint)谁是对的,谁做了错误的验证(Me、XMLSpy、lxml.etree 或 xmllint)
【发布时间】:2017-06-11 21:47:21
【问题描述】:

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

machineDB.xml:20:模式有效性错误:元素“canframe”:未找到 keyref 'busRef' 的键序列 ['remotebus'] 的匹配项。 machineDB.xml 验证失败

有人可以帮忙找人吗?


版本:

Altova XMLSpy 专业版 2016 版本。 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 : (2, 9, 4) 编译的 libxml : (2, 9, 4) 使用的 libxslt : (1, 1, 29) 编译的 libxslt : (1, 1, 29)

xmllint(使用 libxml 版本 20708)

ma​​chineDB.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>

ma​​chinedb.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>

【问题讨论】:

    标签: xml lxml xsd-validation xmllint xmlspy


    【解决方案1】:

    架构包含属性

    vc:minVersion="1.1"
    

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

    使用 .Net Validating reader 它报告它是有效的。 .Net 解析器是 XSD 1.0 解析器,不知道 vc:minVersion 属性,因此忽略它,将其视为 1.0 架构

    在 XSD 1.0 模式下使用 .Xerces 验证无法验证。 Xerces 知道 vc:minVersion 属性,因此忽略了架构,因为它不在 1.1 模式下。

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

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

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

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

    【讨论】:

    • 既然架构中没有任何东西是 XSD 1.1,为什么你认为版本信息与 OP 得到的错误有关?谢谢!
    • 从技术上讲,如果它不符合 1.1,验证器甚至不应该看到模式(一旦它看到属性 vc:minVersion="1.1" 它应该忽略元素的其余部分)。我基本上提供了一些主要解析器的结果,其他解析器如何处理 MinVersion 标签是未知的。正如最后所说,我认为问题出在您尝试的解析器而不是 schema/xml 组合。但是您可能会在其他 1.0 解析器上看到使用此模式的问题。
    【解决方案2】:

    有趣的问题。如果您在没有自定义限制的情况下将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 行为正确。

    【讨论】:

    • 非常感谢,我只是没看出区别。特别是对我来说,由于更多限制,我使用 type="NameType" ,但这仍然是一种奇怪的行为。
    猜你喜欢
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 2022-07-06
    相关资源
    最近更新 更多