为什么此 XML 使用此架构进行验证?

Why does this XML validate with this schema?

一个简单的XML:

<?xml version="1.0"?>
<root>
 <code>
  <command name="EXPORT"/>
 </code>
 <module name="DEMO_">
  <keyword name="TEST123"/>
 </module>
 <!--
 <code>
   <command name="321TEST" foo="bar"/>
   <keyword name="TEST123"/>
 </code>
 -->
</root>

还有一个简单的架构:

<?xml version='1.0'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>

 <xs:simpleType name='name'>
  <xs:restriction base='xs:string'>
   <xs:pattern value='[A-Z]*'/>
  </xs:restriction>
 </xs:simpleType>

 <xs:element name='root'>
  <xs:complexType>
   <xs:choice minOccurs='0' maxOccurs='unbounded'>
    <xs:element name='module'/>
    <xs:element name='code'/>
   </xs:choice>
  </xs:complexType>
 </xs:element>

 <xs:element name='code'>
  <xs:complexType>
   <xs:choice minOccurs='0' maxOccurs='unbounded'>
    <xs:element name='command'/>
   </xs:choice>
  </xs:complexType>
 </xs:element>

 <xs:element name='command'>
  <xs:complexType>
   <xs:attribute name='name' type='name' use='required'/>
  </xs:complexType>
 </xs:element>

 <xs:element name='module'>
  <xs:complexType>
   <xs:attribute name='name' type='name' use='required'/>
  </xs:complexType>
 </xs:element>

</xs:schema>

<root>中允许任意数量的<code><module><code> 可能包含任意数量的 <command><command><module> 有一个必需的属性 name,它必须只包含大写字母。就是这样。

上面的XML是这个架构错误的:

但是 xmllinthttps://www.liquid-technologies.com/online-xsd-validator(至少)仍然说它是有效的:

$ xmllint --schema test.xsd test.xml --noout
test.xml validates

我错过了什么?

如果我取消注释最后一个元素,我会收到无效 name 和不允许的属性 foo 的错误(但 <keyword> 元素仍然不会)。这样就完成了某种验证。

在架构中,您已指定根元素可以包含任意数量的模块或代码元素,但您尚未指定这些元素的类型。

我不确定您要为您的 XML 文档强制执行什么结构。一种可能是以下架构,其中根元素内的模块和代码元素具有非常特定的结构:

<?xml version='1.0'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>

    <xs:simpleType name='name'>
        <xs:restriction base='xs:string'>
            <xs:pattern value='[A-Z]*'/>
        </xs:restriction>
    </xs:simpleType>

    <xs:element name='root'>
        <xs:complexType>
            <xs:choice minOccurs='0' maxOccurs='unbounded'>
                <xs:element name='module' type ="moduleType"/>
                <xs:element name='code' type="codeType"/>
            </xs:choice>
        </xs:complexType>
    </xs:element>

    <xs:element name='code' type="codeType"/>
    <xs:element name='command' type="commandType"/>
    <xs:element name='module' type="moduleType"/>

    <xs:complexType name="codeType">
        <xs:choice minOccurs='0' maxOccurs='unbounded'>
            <xs:element name='command'/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="commandType">
        <xs:attribute name='name' type='name' use='required'/>
    </xs:complexType>

    <xs:complexType name="moduleType">
        <xs:attribute name='name' type='name' use='required'/>
    </xs:complexType>

</xs:schema>

如果您尝试根据此模式验证您的 XML 文档,您会发现(在其他验证错误中)值 'DEMO_' 无效。

您的错误(一个常见错误)是在内容模型中使用了 <xs:element name="ABC"/>,而您本打算使用 <xs:element ref="ABC"/>。您的模式是合法的,但是您定义了没有关联类型的局部元素声明,而不是引用具有关联类型的全局元素声明。