XSD条件类型赋值默认类型混淆?

时间:2017-12-18 10:05:18

标签: xml xsd xsd-validation xml-validation xsd-1.1

我尝试使用CTA设计XSD。 我有以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="test.xsd">
    <person version="1">
        <firstname>toto</firstname>
        <lastname>tutu</lastname>
    </person>
    <person version="2">
        <firstname>toto</firstname>
        <lastname>tutu</lastname>
        <birthdate>2017-12-18</birthdate>
    </person>
</persons>

XSD看起来像:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
    elementFormDefault="qualified"
    vc:minVersion="1.1"> 

    <xs:complexType name="person_v1">
        <xs:sequence>
            <xs:element name="firstname" type="xs:token"/>
            <xs:element name="lastname" type="xs:token"/>
        </xs:sequence>
        <xs:attribute name="version" type="xs:token" use="required" fixed="1"/>
    </xs:complexType>

    <xs:complexType name="person_v2">
        <xs:sequence>
            <xs:element name="firstname" type="xs:token"/>
            <xs:element name="lastname" type="xs:token"/>
            <xs:element name="birthdate" type="xs:date"/>
        </xs:sequence>
        <xs:attribute name="version" type="xs:token" use="required" fixed="2"/>
    </xs:complexType>

    <xs:element name="person">
        <xs:alternative test="@version=1" type="person_v1"/>        
        <xs:alternative test="@version=2" type="person_v2"/>
    </xs:element>

    <xs:element name="persons">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="person" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

XML是针对XSD验证的,但在XSD中验证:

  1. 如果我删除版本属性,则验证
  2. 如果我将版本1替换为3,则验证
  3. 如果我删除了所有人的内容,则会进行验证。
  4. 我的XSD上肯定有一些东西丢失了。

1 个答案:

答案 0 :(得分:1)

  
      
  1. 如果我删除版本属性,则验证
  2.   

应该这样,因为当没有xs:alternative个测试匹配时,personCommon Mapping Rules for Element Declarations可以xs:anyType

  
      
  1. 如果我将版本1替换为3,则验证
  2.   

因为它应该与#1相同。

  
      
  1. 如果我删除了所有人的内容,则会进行验证。
  2.   

不,它没有。您可能没有将XML文档与XSD真正关联,或者您可能将实验#3与实验#1或#2结合在一起。

更新了XSD

以下更新的XSD指定默认类型person而不是xs:anyType,以避免出现意外情况#1和#2。请注意,它还使用扩展来将person_v1person_v2的声明的公共部分合并到person_v中,并满足必须从公共基类派生替代类型的要求。 (如果未指定,则xs:anyType通常会被忽视。)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           elementFormDefault="qualified"
           vc:minVersion="1.1"> 
  <xs:complexType name="person_v">
    <xs:sequence>
      <xs:element name="firstname" type="xs:token"/>
      <xs:element name="lastname" type="xs:token"/>
    </xs:sequence>
    <xs:attribute name="version" type="xs:token" use="required"/>
  </xs:complexType>
  <xs:complexType name="person_v1">
    <xs:complexContent>
      <xs:extension base="person_v"/>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="person_v2">
    <xs:complexContent>
      <xs:extension base="person_v">
        <xs:sequence>
          <xs:element name="birthdate" type="xs:date"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:element name="person" type="person_v">
    <xs:alternative test="@version=1" type="person_v1"/>        
    <xs:alternative test="@version=2" type="person_v2"/>
  </xs:element>
  <xs:element name="persons">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="person" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

更新:以下person_v的更新要求该版本为12以解决评论中的问题:< / p>

  <xs:complexType name="person_v">
    <xs:sequence>
      <xs:element name="firstname" type="xs:token"/>
      <xs:element name="lastname" type="xs:token"/>
    </xs:sequence>
    <xs:attribute name="version" use="required">
      <xs:simpleType>
        <xs:restriction base="xs:integer">
          <xs:minInclusive value="1"/>
          <xs:maxInclusive value="2"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>