为什么此 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是这个架构错误的:
<module>
元素的 name
包含下划线。
<module>
元素包含一个从未定义或允许的 <keyword>
元素。
但是 xmllint
和 https://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"/>
。您的模式是合法的,但是您定义了没有关联类型的局部元素声明,而不是引用具有关联类型的全局元素声明。
一个简单的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是这个架构错误的:
<module>
元素的name
包含下划线。<module>
元素包含一个从未定义或允许的<keyword>
元素。
但是 xmllint
和 https://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"/>
。您的模式是合法的,但是您定义了没有关联类型的局部元素声明,而不是引用具有关联类型的全局元素声明。