XSD 条件类型赋值默认类型混淆? [英] XSD conditional type assignment default type confusion?

查看:25
本文介绍了XSD 条件类型赋值默认类型混淆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<person version="1"><firstname>toto</firstname><lastname>短裙</lastname></人><person version="2"><firstname>toto</firstname><lastname>短裙</lastname><生日>2017-12-18</生日></人></人>

XSD 看起来像:

<xs:complexType name="person_v1"><xs:序列><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:序列><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:序列><xs:element ref="person" maxOccurs="unbounded"/></xs:sequence></xs:complexType></xs:element></xs:schema>

根据 XSD 验证 XML,但在 XSD 中:

  1. 如果我删除版本属性,它会验证,
  2. 如果我用 3 替换版本 1,它会验证,
  3. 如果我删除了 person 的所有内容,它就会生效.

我的 XSD 上一定缺少某些东西.

解决方案

  1. 如果我删除版本属性,它会验证,

理所当然,因为当没有 xs:alternative 测试匹配时,person 可以是 xs:anyType 每个 元素声明的通用映射规则.

<块引用>

  1. 如果我用 3 替换版本 1,它会验证,

出于与 #1 相同的原因,应该这样做.

<块引用>

  1. 如果我删除了 person 的所有内容,它就会生效.

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

更新了 XSD

以下更新的 XSD 指定了默认类型 person 而不是 xs:anyType 以避免意外 #1 和 #2.请注意,它还使用扩展将 person_v1person_v2 声明的公共部分合并到 person_v 中,并满足替代类型必须派生自一个公共基类.(未指定时,它是 xs:anyType,通常不会引起注意.)

<xs:complexType name="person_v"><xs:序列><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:序列><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:序列><xs:element ref="person" maxOccurs="unbounded"/></xs:sequence></xs:complexType></xs:element></xs:schema>

<小时>

更新:这是对 person_v 的更新,要求版本为 12 以解决问题在评论中:

 <xs:序列><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>

I try to design a XSD with CTA. I have the following 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>

The XSD looks like:

<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>

The XML is validated against the XSD, but in the XSD:

  1. If I delete the version attribute, it validates,
  2. If I replace the version 1 by 3, it validates,
  3. If I delete all the content of person, it validates.

There must be something missing on my XSD.

解决方案

  1. If I delete the version attribute, it validates,

As it should, because when no xs:alternative tests match, person can be xs:anyType per Common Mapping Rules for Element Declarations.

  1. If I replace the version 1 by 3, it validates,

As it should for the same reason as #1.

  1. If I delete all the content of person, it validates.

No, it doesn't. You may not have truly associated the XML document with your XSD, or you may have accidently combined experiment #3 with experiments #1 or #2.

Updated XSD

The following updated XSD specifies a default type of person rather than xs:anyType to avoid the surprises #1 and #2. Note that it also uses extension to consolidate common parts of the declarations of person_v1 and person_v2 into person_v and to satisfy the requirement that the alternative types must be derived from a common base class. (When unspecified, it's xs:anyType and typically goes unnoticed.)

<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>


Update: Here's an update to person_v to require that version be 1 or 2 to address a concern in the comments:

  <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>

这篇关于XSD 条件类型赋值默认类型混淆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆