1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

说说 xml schema

Posted at

简单说 xml schema 就是用 xml 来描述 xml 格式的特定 xml 文件.通常文件后缀是 xsd, 它来自于 XML Schema Definition 的简写.
看看最简单的例子:

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

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

上面的这个 xsd 文件描述了怎么样一个 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>

###xsd 文件都做了什么呢?

  • 它可以规定究竟有什么元素和属性可以出现在被描述的 xml 文件中
  • 一个 xml 根节点到底可以包含什么子元素
  • 元素或者属性的字段类型
  • 元素和属性的默认值等

为什么要学习 XML Schema 呢?

在 xml 的世界中, 我们经常会遇到各种各样的不同的 xml 文件.他们通常都是通过 xml schema 来规范约束的, 区别于 DTD 文件的是它本身就是 xml 文件.

XML schema 支持数据类型

这个可能是区别于其他约束 xml 的描述文件的最大特定

  • 它可以很容易的描述这个文件到底有什么内容
  • 验证数据的准确性
  • 定义数据
  • 数据格式
  • 不用的数据格式之间的转换

xml schema 继续使用 xml 语法

  • 你不需要多学习其他的语言语法等
  • 你用 xml 编辑器就可以编辑 schema
  • 你可以通过 xml 的读取方式来解析 schema 文件
  • 通过 xml 文件可以生成 schema 文件
  • 可以通过 XSLT 来转换格式

XML schemas 是可以扩展的因为它是 xml 写就

有了这个扩展性就可以做更多的事情:

  • 复用 schema
  • 定义新是数据类型基于标准的类型
  • 在一个 xml 文档中引用多个 schema 文件

xml schema 增强的数据通信的安全性

当发送数据到对方的时候,双方都能够到期望的结果是必须的. 通过 xml schema, 发送方可以描述数据以至于让接收方能够理解.
例如一个数据03-11-2017是什么意思呢, 是3月11号还是11月3号呢?
但是通过 xml 的元素表示,它就是简单的:

<date type='date'>2017-03-11</date>

这样双方都理解了它是一个 date 格式的数据, 就是 YYYY-MM-DD 的格式.

格式好并不够

一个格式完好的 xml 文档它是符合 xml 语法的存在, 如:

  • 必须以 xml 定义说明开始
  • 必须有一个根节点
  • 开始符必须和结束节点匹配
  • 元素大小写敏感
  • 所有的元素需要结束
  • 所有元素需要正确的嵌套
  • 所有的属性值应该括号包围
  • 实体必须有特定的字符描述.

XSD 的元素

对于 xml schema 文件来说, <schema> 是它的根节点.

<?xml version="1.0"?>

<xs:schema>
...
...
</xs:schema>

这个<schema>可以包含很多的属性, 看上去像这样:

<?xml version="1.0"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://www.w3schools.com"
xmlns="https://www.w3schools.com"
elementFormDefault="qualified">
...
...
</xs:schema>

而其中

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

就表明了这个 schema 文件里用到的元素和数据类型都是来自"http://www.w3.org/2001/XMLSchema" 这个命名空间里的. 同时指定所有来自这个命名空间里的元素和数据类型都应该使用 xs 作为前缀.

targetNamespace="https://www.w3schools.com"

它说明了定义在这个schema的元素*( note, to, from, heading, body)都是来自这个https://www.w3schools.com" 命名空间的,
xmlns="https://www.w3schools.com"表明它是默认的命名空间, elementFormDefault="qualified"是表明所有使用该 schema的 xnl 文件里元素都应该使用命名空间约束.

引用这个 schema 文件到 xml 里

<?xml version="1.0"?>

<note xmlns="https://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.w3schools.com note.xsd">

<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

这里, xmlns="https://www.w3schools.com"它说明默认的命名空间定义,也就是说所有在这里定义出现的元素都是从这个 schema 的命名空间里出现的.

而一旦你有了 xml schema 实例的命名空间,xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 你可以使用 schemaLocation 属性来定义,它有两个值, 通过空格隔开, 第一个是命名空间, 第二是 xml schema 文件的地址.

xsi:schemaLocation="https://www.w3schools.com note.xsd"

XSD 的简单元素

XSD 终归主干一件事情就是定义 xml 文件里的元素.
一个简单的元素也就是说它只能够包含文本,不能够包含子元素或者属性等.

  • 如何定义呢:
<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>

它实际对应的 xsd 就是:

<xs:element name="lastname" type="xs:string"/>
<xs:element name="age" type="xs:integer"/>
<xs:element name="dateborn" type="xs:date"/>

而对于简单元素的默认和固定值又是什么样子

简单元素可以指定默认值或者是固定值.

<xs:element name="color" type="xs:string" default="red"/>
# or
<xs:element name="color" type="xs:string" fixed="red"/>

xsd 的属性

所有的属性都是按照简单元素的方式来定义的

  • 什么是属性呢?
    简单元素不能够有属性,如果一个元素有了属性,那它就是一个复合类型,但是这个属性它本身是以简单元素声明的.

  • 怎么定义?

<xs:attribute name="xxx" type="yyy"/>

其实上面这个虽然是属性的定义,但是和简单元素也基本上一样的, xxx 就是名字,而 yyy 就是类型

xs:string
xs:decimal
xs:integer
xs:boolean
xs:date
xs:time

例子,

# 如这个元素

<lastname lang="EN">Smith</lastname>
#对应的 xsd

<xs:attribute name="lang" type="xs:string"/>

同样对应属性的默认值和固定值:

<xs:attribute name="lang" type="xs:string" default="EN"/>

# or

<xs:attribute name="lang" type="xs:string" fixed="EN"/>

另外对于属性,它本身还可以是可选的

<xs:attribute name="lang" type="xs:string" use="required"/>

xsd 里对于值的约束

对于元素或者属性的值, 都是可以进行约束的.如下面的约束例子:

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

它就约束了 age 这个元素的值应该是0-120的.

而且还可以这样约束一个值只能是 set 里的一项:

<xs:element name="car">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:enumeration value="Audi"/>
      <xs:enumeration value="Golf"/>
      <xs:enumeration value="BMW"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

同样上面的写法可以变换成用来约束它的一个属性:

<xs:element name="car" type="carType"/>

<xs:simpleType name="carType">
  <xs:restriction base="xs:string">
    <xs:enumeration value="Audi"/>
    <xs:enumeration value="Golf"/>
    <xs:enumeration value="BMW"/>
  </xs:restriction>
</xs:simpleType>

接着我们就来说说 xsd 里怎么描述复杂类型吧

xsd complex 元素

所谓一个复杂元素就是它还包含了子元素或者属性

  • 什么是复杂元素

一个复杂元素就是包含了子元素或者属性的元素, 有四种:

  • 空元素
  • 元素只包含了其他元素
  • 元素只包含了文本
  • 元素包含了其他元素或者文本.

*这里说的元素都可以有属性

复杂元素

# A complex XML element, "product", which is empty:
<product pid="1345"/>
# A complex XML element, "employee", which contains only other elements:

<employee>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
</employee>
# A complex XML element, "food", which contains only text:

<food type="dessert">Ice cream</food>

#A complex XML element, "description", which contains both elements and text:

<description>
It happened on <date lang="norwegian">03.03.99</date> ....
</description>

怎么定义复杂元素

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

我们可以通过2中方式来定义复杂元素.

  1. 就是直接通过复杂类型来生命元素:
<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>来围绕的, 这就说明需要按照声明的顺序来书写.

  1. 这个 employee 元素可以有一个类型的属性来引用到一个复杂元素.
<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 空元素

一个所谓的空复杂元素就是它不能够有内容,只能有属性

<product prodid="1345" />
<xs:element name="product">
  <xs:complexType>
    <xs:attribute name="prodid" type="xs:positiveInteger"/>
  </xs:complexType>
</xs:element>

xsd 定义只有元素的复杂元素

<person>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
</person>

可以这样定义:

<xs:element name="person" type="persontype"/>

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

xsd 只包含文本

xsd 复合元素

<letter>
  Dear Mr.<name>John Smith</name>.
  Your order <orderid>1032</orderid>
  will be shipped on <shipdate>2001-07-13</shipdate>.
</letter>
<xs:element name="letter" type="lettertype"/>

<xs:complexType name="lettertype" mixed="true">
  <xs:sequence>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="orderid" type="xs:positiveInteger"/>
    <xs:element name="shipdate" type="xs:date"/>
  </xs:sequence>
</xs:complexType>

ref

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?