首页 > 解决方案 > 限制 XSD,使其不允许根元素上的属性

问题描述

我需要使用以下 XSD 验证 XML

<xs:element name="root" type="rootType"/>
<xs:element name="names" type="nameType"/>
    <xs:complexType name="rootType" mixed="true">
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">                
                <xs:element name="names" minOccurs="0" maxOccurs="unbounded" type="nameType"/>
                <xs:element name="root" minOccurs="0" maxOccurs="unbounded" type="rootType"/>                
            </xs:choice>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="nameType" mixed="true">
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">                
                <xs:element name="names" minOccurs="0" maxOccurs="unbounded" type="nameType"/>
                <xs:element name="root" minOccurs="0" maxOccurs="unbounded" type="rootType"/> 
            </xs:choice>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string"/>
    </xs:complexType>

这样,XSD 不应允许 XML 中的根元素具有“名称”属性。

例如:XSD 应该认为以下 XML 是有效的

<root>
<names name="abc"></names>
<root name="xyz"></root>
</root>

并且以下内容无效,因为 xml 的根元素具有 name 属性。

<root name="rootElement">
<names name="abc"></names>
<root name="xyz"></root>
</root>

但是,如果同一个元素作为子元素出现,那么它可以具有 name 属性。请让我们知道这是否可以使用 XSD,如果可以,我们该怎么做?

标签: xmlxsdschemaxsd-validation

解决方案


定义不带名称属性的 rootType:

<xs:complexType name="rootTypeWithoutName" mixed="true">
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">                
                <xs:element name="names" minOccurs="0" maxOccurs="unbounded" type="nameType"/>
                <xs:element name="root" minOccurs="0" maxOccurs="unbounded" type="rootTypeWithName"/>                
            </xs:choice>
        </xs:sequence>
    </xs:complexType>

然后定义一个允许名称的扩展类型:

<xs:complexType name="rootTypeWithName" mixed="true">
  <xs:extension base="rootTypeWithoutName">
   <xs:attribute name="name" type="xs:string"/>
  </xs:extension>
</xs:complexType>

在根的全局元素声明中,使用type="rootTypeWithoutName". 在嵌套根元素的局部元素声明中(如上所示),使用 type rootTypeWithName

这个我没有测试过,所以可能有语法错误,但原理应该是合理的。


推荐阅读