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

问题描述:

我试图验证以下XML与以下xsd文件在同一文件夹中。根据Altova XMLSpy的说法,这是完全有效的,但是为了帮助一些没有许可证的同事发现基本错误,我尝试使用python和'lxml.etree'验证文件,并使用xmllint进行验证。这两个表示xml对于相同的消息无效:谁是对的,谁做错误的验证(我,XMLSpy,lxml.etree或xmllint)

machineDB.xml:20:模式有效性错误:元素'canframe':找不到keyref'busRef'的键序列''remotebus' 。 machineDB.xml无法验证

有人可以帮助找到任何人的错?


版本:

Altova的XMLSpy的专业版版2016版本。 2 SP1(64)

lxml.etree版本

的Python:sys.version_info(主要= 2,次要= 7,微= 11, releaselevel = '最终',串行= 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)

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_reftypecanbusxs: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的行为是正确的。

+0

非常感谢,我只是没有看到区别。特别是对于我来说,由于更多的限制,我使用type =“NameType”,但这仍然是一种奇怪的行为。 –

该架构包含属性

vc:minVersion="1.1" 

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

使用.Net验证阅读器报告它是有效的。 .Net解析器是一个XSD 1.0解析器,并且不知道vc:minVersion属性,因此只是忽略它,将其视为1.0架构

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

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

其他不支持XSD 1.1的解析器可能无论如何。

可以肯定的是,我不认为架构包含1.1特定的任何东西(语法或功能),所以我不知道为什么它被标记为1.1架构。

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

+0

由于架构中没有任何内容是XSD 1.1,您为什么认为版本信息与OP所收到的错误有关?谢谢! –

+0

从技术上讲,如果验证程序不符合1.1规范(只要它看到属性vc:minVersion =“1.1”,应该忽略该元素的其余部分),验证程序甚至不应该看到该模式。我基本上提供了一些主要解析器的结果,其他解析器如何处理MinVersion标记是未知的。正如最后所说,我认为问题在于你尝试的解析器不是schema/xml组合。但是可能你会发现在其他1.0解析器上使用这个模式的问题。 – Sprotty