XSD学习记录

XSD学习记录

主要来自菜鸟教程的学习笔记,结合其他博客作了一些综合的学习,对最基本的内容整理了本markdown格式的单文档。

概念

  1. 全称
    XML Schema Definition,作用是定义 XML 文档的合法构建模块,类似DTD.
  2. 示例
    请看这个名为 “note.xml” 的 XML 文档:
    <?xml version="1.0"?>
    <note>
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
    </note>
    
    下面这个例子是一个名为 “note.xsd” 的 XML Schema 文件,它定义了上面那个 XML 文档( “note.xml” )的元素:
       <?xml version="1.0"?>
       <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
       targetNamespace="http://www.w3schools.com"
       xmlns="http://www.w3schools.com"
       elementFormDefault="qualified">
       <xs:element name="note">
       <xs:complexType>
           <xs:sequence>
           <xs:element name="to" type="xs:string"/>
           <xs:element name="from" type="xs:string"/>
           <xs:element name="heading" type="xs:string"/>
           <xs:element name="body" type="xs:string"/>
           </xs:sequence>
       </xs:complexType>
       </xs:element>
       </xs:schema>     
    

在 XML 文档中引用 Schema

以下的这个XML文档(为maven项目的pom文件)含有对XML Schema的引用

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
……
</project>

下面的代码片断:

xmlns="http://maven.apache.org/POM/4.0.0"

规定了默认命名空间的声明。此声明会告知schema验证器,在此XML文档中使用的所有元素都被声明于"http://maven.apache.org/POM/4.0.0"这个命名空间。

现在来看文件头中剩下的,看上去更为复杂的部分:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"

  根据之前的知识我们可以理解,xmlns:xsi定义了一个命名空间前缀xsi,对应的唯一字符串http://www.w3.org/2001/XMLSchema-instance。但是读者会发现,这个xmlns:xsi在不同的xml文档中似乎都会出现。这是因为,xsi 已经成为了一个业界默认的用于 XSD((XML Schema Definition) 文件的命名空间。
那么, 有了上述的理解, 再来看

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"

上面这行的语法其实是, xsi:schemaLocation = "键" “值”
即xsi命名空间下schemaLocation元素的值为一个由空格分开的键值对

  • 前一个“键” http://maven.apache.org/POM/4.0.0 指代【命名空间】,只是一个全局唯一字符串而已.
  • 后一个值指代 【XSD location URI】 , 这个值指示了前一个命名空间所对应的 XSD 文件的位置, xml parser 可以利用这个信息获取到 XSD 文件, 从而通过 XSD 文件对
    所有属于 命名空间 http://maven.apache.org/POM/4.0.0 的元素结构进行校验, 因此这个值必然是可以访问的, 且访问到的内容是一个 XSD 文件的内容

XSD <schema>元素 (根元素)

<schema> 元素是每一个 XML Schema 的根元素。

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.runoob.com"
xmlns="http://www.runoob.com"
elementFormDefault="qualified">...
...
</xs:schema>

以下代码片段:

xmlns:xs="http://www.w3.org/2001/XMLSchema"

显示 schema 中用到的元素和数据类型来自命名空间 “http://www.w3.org/2001/XMLSchema”。同时它还规定了来自命名空间 “http://www.w3.org/2001/XMLSchema” 的元素和数据类型应该使用前缀 xs:

这个片段:

targetNamespace="http://www.runoob.com"  

显示被此 schema 定义的元素 (note, to, from, heading, body) 来自命名空间: “http://www.runoob.com”。

这个片断:

xmlns="http://www.runoob.com"

指出默认的命名空间是 “http://www.runoob.com”。

这个片断:

elementFormDefault="qualified"

指出任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定。

XSD 简易元素

  • 什么是简易元素?
    简易元素指那些仅包含文本的元素。它不会包含任何其他的元素或属性。
    不过,"仅包含文本"这个限定却很容易造成误解。文本有很多类型。它可以是XML Schema定义中包括的类型中的一种(布尔、字符串、数据等等),或者它也可以是您自行定义的定制类型。
    您也可向数据类型添加限定(即facets),以此来限制它的内容,或者您可以要求数据匹配某种特定的模式。
  • 定义简易元素
    定义简易元素的语法:
    <xs:element name="xxx" type="yyy"/>
    此处 xxx 指元素的名称,yyy指元素的数据类型。XML Schema拥有很多内建的数据类型。
  • 最常用的类型是:
    xs:string
    xs:decimal
    xs:integer
    xs:boolean
    xs:date
    xs:time
  • 实例
    这是一些 XML 元素:
    <lastname>Refsnes</lastname>
    <age>36</age>
    <dateborn>1970-03-27</dateborn>
    
    这是相应的简易元素定义:
    <xs:element name="lastname" type="xs:string"/>
    <xs:element name="age" type="xs:integer"/>
    <xs:element name="dateborn" type="xs:date"/>
    
  • 简易元素的默认值和固定值
    简易元素可拥有指定的默认值或固定值。当没有其他的值被规定时,默认值就会自动分配给元素。
    在下面的例子中,默认值是 “red”:
    <xs:element name="color" type="xs:string" default="red"/>
    固定值同样会自动分配给元素,并且您无法规定另外一个值。
    在下面的例子中,固定值是 “red”:
    <xs:element name="color" type="xs:string" fixed="red"/>

XSD 属性(attribute)

所有的属性均作为简易类型来声明。

  • 什么是属性?

简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。

  • 如何声明属性?
    定义属性的语法是
    <xs:attribute name="xxx" type="yyy"/>
    在此处,xxx 指属性名称,yyy则规定属性的数据类型。XML Schema 拥有很多内建的数据类型。

  • 实例
    这是带有属性的 XML 元素:
    <lastname lang="EN">Smith</lastname>
    这是对应的lang属性定义:
    <xs:attribute name="lang" type="xs:string"/>

  • 属性默认值/固定值/可选/必选

XSD 限定(Facets)

限定(restriction)用于为XML元素或者属性定义可接受的值。对XML元素的限定被称为facet。

  • 对值的限定
    下面的例子定义了带有一个限定且名为 “age” 的元素。age 的值不能低于 0 或者高于 120:
    <xs:element name="age">
    <xs:simpleType>
        <xs:restriction base="xs:integer">
        <xs:minInclusive value="0"/>
        <xs:maxInclusive value="120"/>
        </xs:restriction>
    </xs:simpleType>
    </xs:element>
    

其它限制模式还有很多,不在深入研究

XSD 复合元素

复合元素包含了其他的元素及/或属性。

  • 什么是复合元素?
    复合元素指包含其他元素及/或属性的 XML 元素。

  • 有四种类型的复合元素:
    空元素
    包含其他元素的元素
    仅包含文本的元素
    包含元素和文本的元素
    注意:上述元素均可包含属性!

  • 复合元素的例子

    • 复合元素,“product”,是空的:
      <product pid="1345"/>
    • 复合元素,“employee”,仅包含其他元素:
      <employee>
          <firstname>John</firstname>
          <lastname>Smith</lastname>
      </employee>
      
    • 复合 XML 元素,“food”,仅包含文本:
      <food type="dessert">Ice cream</food>
    • 复合XML元素,"description"包含元素和文本:
      <description>
        It happened on   
        <date lang="norwegian">03.03.99</date>  
        ....  
      </description>
      

如何定义复合元素

请看这个复合 XML 元素,“employee”,仅包含其他元素:

<employee>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
</employee>

在 XML Schema 中,我们有两种方式来定义复合元素:

  1. 通过命名此元素,可直接对"employee"元素进行声明,就像这样:

    <xs:element name="employee">
    <xs:complexType>
        <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    </xs:element>
    

    假如您使用上面所描述的方法,那么仅有 “employee” 可使用所规定的复合类型。请注意其子元素,“firstname” 以及 “lastname”,被包围在指示器 <sequence>中。这意味着子元素必须以它们被声明的次序出现。您会在XSD 指示器这一节学习更多有关指示器的知识。

  2. “employee” 元素可以使用 type 属性,这个属性的作用是引用要使用的复合类型的名称:

    <xs:element name="employee" type="personinfo"/>
    <xs:complexType name="personinfo">
    <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
    </xs:sequence>
    </xs:complexType>
    

    如果您使用了上面所描述的方法,那么若干元素均可以使用相同的复合类型,比如这样:

    <xs:element name="employee" type="personinfo"/>
    <xs:element name="student" type="personinfo"/>
    <xs:element name="member" type="personinfo"/>
    <xs:complexType name="personinfo">
    <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
    </xs:sequence>
    </xs:complexType>
    

    您也可以在已有的复合元素之上以某个复合元素为基础,然后添加一些元素,就像这样:

    <xs:element name="employee" type="fullpersoninfo"/>
    <xs:complexType name="personinfo">
    <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
    </xs:sequence>
    </xs:complexType>
    <xs:complexType name="fullpersoninfo">
    <xs:complexContent>
        <xs:extension base="personinfo">
        <xs:sequence>
            <xs:element name="address" type="xs:string"/>
            <xs:element name="city" type="xs:string"/>
            <xs:element name="country" type="xs:string"/>
        </xs:sequence>
        </xs:extension>
    </xs:complexContent>
    </xs:complexType>
    

XSD 指示器

通过指示器,我们可以控制在文档中使用元素的方式。

  • 指示器,有七种指示器:
    Order指示器:

    • All
    • Choice
    • Sequence

    Occurrence指示器:

    • maxOccurs
    • minOccurs

    Group指示器:

    • Group name
    • attributeGroup name

Order指示器

Order 指示器用于定义元素的顺序。

  • All 指示器
    <all>指示器规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次:

    <xs:element name="person">
    <xs:complexType>
        <xs:all>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
        </xs:all>
    </xs:complexType>
    </xs:element>
    

    注意: 当使用<all>指示器时,你可以把<minOccurs>设置为0 或者1,而只能把<maxOccurs>指示器设置为 1(稍后将讲解 minOccurs 以及<maxOccurs)。

  • Choice 指示器
    <choice>指示器规定可出现某个子元素或者可出现另外一个子元素(非此即彼):

  • Sequence 指示器
    <sequence> 规定子元素必须按照特定的顺序出现:

Occurrence指示器

Occurrence 指示器用于定义某个元素出现的频率。
注意:
对于所有的 “Order” 和 “Group” 指示器(any、all、choice、sequence、group name 以及 group reference),其中的 maxOccurs 以及 minOccurs 的默认值均为 1。

  • maxOccurs 指示器
    <maxOccurs>指示器可规定某个元素可出现的最大次数:

    <xs:element name="person">
    <xs:complexType>
        <xs:sequence>
        <xs:element name="full_name" type="xs:string"/>
        <xs:element name="child_name" type="xs:string" maxOccurs="10"/>
        </xs:sequence>
    </xs:complexType>
    </xs:element>
    

    上面的例子表明,子元素 “child_name” 可在 “person” 元素中最少出现一次(其中 minOccurs 的默认值是 1),最多出现 10 次。

  • minOccurs 指示器
    <minOccurs>指示器可规定某个元素能够出现的最小次数:

    <xs:element name="person">
    <xs:complexType>
        <xs:sequence>
        <xs:element name="full_name" type="xs:string"/>
        <xs:element name="child_name" type="xs:string" maxOccurs="10" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
    </xs:element>
    

    上面的例子表明,子元素 “child_name” 可在 “person” 元素中出现最少 0 次,最多出现 10 次。

    提示: 如需使某个元素的出现次数不受限制,请使用 maxOccurs=“unbounded” 这个声明:

Group 指示器

Group指示器用于定义相关的数批元素。
 个人理解: 数批元素表示元素/

  • 元素组
      元素组通过 group 声明进行定义,必须在 group声明内部定义一个all、choice 或者 sequence元素。
      下面这个例子定义了名为"persongroup"的group,它定义了必须按照精确的顺序出现的一组元素:

    <xs:group name="persongroup">
    <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
        <xs:element name="birthday" type="xs:date"/>
    </xs:sequence>
    </xs:group>
    

    在您把 group 定义完毕以后,就可以在另一个定义中引用它了:

    <xs:group name="persongroup">
        <xs:sequence>
            <xs:element name="firstname" type="xs:string"/>
            <xs:element name="lastname" type="xs:string"/>
            <xs:element name="birthday" type="xs:date"/>
        </xs:sequence>
    </xs:group>
    <xs:element name="person" type="personinfo"/>
    <xs:complexType name="personinfo">
        <xs:sequence>
            <xs:group ref="persongroup"/>
            <xs:element name="country" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    
  • 属性组
    属性组通过 attributeGroup 声明来进行定义。

    下面这个例子定义了名为 “personattrgroup” 的一个属性组:

    <xs:attributeGroup name="personattrgroup">
        <xs:attribute name="firstname" type="xs:string"/>
        <xs:attribute name="lastname" type="xs:string"/>
        <xs:attribute name="birthday" type="xs:date"/>
    </xs:attributeGroup>
    

    在您已定义完毕属性组之后,就可以在另一个定义中引用它了,就像这样:

    <xs:attributeGroup name="personattrgroup">
        <xs:attribute name="firstname" type="xs:string"/>
        <xs:attribute name="lastname" type="xs:string"/>
        <xs:attribute name="birthday" type="xs:date"/>
    </xs:attributeGroup>
    <xs:element name="person">
        <xs:complexType>
            <xs:attributeGroup ref="personattrgroup"/>
        </xs:complexType>
    </xs:element>
    
上一篇:Spring配置文件中xsd版本号的问题


下一篇:XSD数据类型之日期/时间数据类型