谁是对的,谁做了错误的验证(我、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_ref
和 canbus
的 type
设置为 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 架构。
但是回到你得到的错误,我认为这是你使用的解析器的一个怪癖。
我试图用同一文件夹中随后的 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_ref
和 canbus
的 type
设置为 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 架构。
但是回到你得到的错误,我认为这是你使用的解析器的一个怪癖。