限制XSD,使其不允许根元素上的属性

时间:2018-08-17 11:58:20

标签: xml xsd schema xsd-validation

我需要使用以下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是否可行,如果可以,怎么办?

1 个答案:

答案 0 :(得分:0)

定义没有名称属性的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>

在root的全局元素声明中,使用type="rootTypeWithoutName"。在嵌套根元素的本地元素声明中(如上所示),使用类型rootTypeWithName

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