XML学习笔记(三):XML规范:Schema详解

前端之家收集整理的这篇文章主要介绍了XML学习笔记(三):XML规范:Schema详解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、XML Schema 规范

1、简介:

1)XmlSchema 也是一种定义和描述Xml文档结构域内容的模式语言,其出现是为了克服DTD的局限性。

2)XmlSchema与DTD:

①、XmlSchema符合Xml语法结构,其就是一个Xml。Dom、Sax等api可以解析XmlSchema文档中的内容

②、XmlSchema对名称空间支持的非常好。

③、XmlSchema 比Xml DTD支持更多的数据类型,并支持用户自定义新的数据类型。如DTD不能规定文本的类型为数字、字母等,但是Schema可以细致的约束。

④、XmlSchema 不能像DTD一样定义实体(Entity),比DTD更加复杂。XmlSchema 正在取代DTD。


2、XML Schema 入门

1)XmlSchema也是一个xml文件,其扩展名通常为.xsd。

2)XmlSchema文档必须有一个根节点,并且这个根节点固定为<Schema>

3)一个XmlSchema,通常称为模式文档(约束文档),遵循这个文档写的xml称之为实例文档。

4)编写一个约束文档后,通常需要把则个文件中声明的元素绑定到一个URI地址上,即定义为一个命名空间,以后xml文件就可以通过这个URI(命名空间)来告诉解析引擎,xml文档中编写的元素来自哪里,被谁约束。


5)案例:

①、XmlSchema文件如下:具体语法先省略,先弄明白根元素中的属性的含义。

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
		targetNamespace="http://www.example.org/NewXMLSchema" 
		xmlns:tns="http://www.example.org/NewXMLSchema" 
		elementFormDefault="qualified">

	<element name="书架"> <!--声明<书架>元素-->
		<complexType><!--声明<书架>元素为复杂类型-->
			<sequence maxOccurs="unbounded"><!--声明<书架>元素 sequence-有顺序; maxOccurs-无上限-->
				<element name="书"><!--声明<书>元素-->
					<complexType>
						<sequence>
							<element name="书名" type="string"></element><!--声明<书名>等元素的类型为string-->
							<element name="作者" type="string"></element>
							<element name="售价" type="string"></element>
						</sequence>
					</complexType>
				</element>
			</sequence>
		</complexType>
	</element>
	
</schema>


<!--声明的这个 schema 文件一定需要绑定要一个命名空间(即定义为一个Namespace,供其他xml文件使用): targetNamespace="http://www.example.org/NewXMLSchema"-->

<!--elementFormDefault:"qualified"-定义的所有元素都绑定为这个命名空间; unqualified:表示只有根元素绑定为这个命名空间-->


A、xmlns:引入命名空间(namespace):默认是W3C的。这个默认引用,只能出现一次。非默认引用需要加别名:如xmlns:tns="http://www.example.org/NewXMLSchema" ,增加了别名 tns 。一个文档可以引入多个命名空间。

B、targetNamespace:定义命名空间,其实XmlSchema的本质就是定义一个命名空间,共其他Xml引用。这边的命名空间定义为URI为"http://www.example.org/NewXMLSchema" ,引用的时候也必须是这个。

C、elementFormDefault:控制元素。有两个取值:"qualified"-定义的所有元素都绑定为这个命名空间; unqualified:表示只有根元素绑定为这个命名空间。

D、attributeFormDefault:控制属性的。用法与elementFormDefault一样。


②、引用这个Xml Schema 的Xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<书架 xmlns="http://www.example.org/NewXMLSchema"
	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	 xsi:schemaLocation = "http://www.example.org/NewXMLSchema NewXMLSchema.xsd">

	<书>
		<书名>XML基础</书名>
		<作者>SAM-SHO</作者>
		<售价>28.00元</售价>
	</书>
</书架>

<!--xmlns="http://www.example.org/NewXMLSchema": 引入命名空间约束,只是虚的路径,需要 schemaLocation具体指定位置-->
<!--xsi:schemaLocation: 指定具体的命名空间所指向的文件,需要具体路径 ,如d://a/NewXMLSchema.xsd 。又需要指定xsi是什么东西?-->
<!--xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance": 指定  xsi 来自的命名空间为 W3C -->

A、xmlns:引入命名空间,默认使用方法(也可以使用别名)。这个地址只是"虚"的路径,需要 schemaLocation具体指定位置

B、schemaLocation:辅助xmlns引入“实”的命名空间,指定具体的命名空间所指向的文件,需要具体路径。2部分组成:定义好的命名空间路径 + 具体schema文件的路径

C、xsi:schemaLocation的使用用到了xsi,所以使用xmlns:xsi指定为来自的命名空间为 W3C,固定用法


③、我们再来简单看下Tomcat的web.xml文件中Xml Schema的使用:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

A、引入“虚”的命名空间:xmlns="http://java.sun.com/xml/ns/javaee"

B、指定“实”的命名空间:xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

路径为:http://java.sun.com/xml/ns/javaee

具体Schema文件路径:http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd。我们自己亲自去下载这个文件

C、指定xsi别名命名空间为来自W3C。


D、手动下载下来的web-app_2_5.xsd文档很大,我只把根元素贴出:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
	    targetNamespace="http://java.sun.com/xml/ns/javaee"
	    xmlns:javaee="http://java.sun.com/xml/ns/javaee"
	    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	    elementFormDefault="qualified"
	    attributeFormDefault="unqualified"
	    version="2.5">



3、XML Schema 语法

XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD)。XML Schema 语法在W3C的手册中非常详细,这边只简单介绍重要的几个语法。


1)简单的类型:——simpleType

①、简易元素:只包含文本的元素,它不会包含任何其他的元素或属性

A、定义简易元素的语法:element 关键字

<xs:element name="xxx" type="yyy"/>
此处 xxx 指元素的名称,yyy 指元素的数据类型。XML Schema 拥有很多内建的数据类型。最常用的类型为:
xs:string
xs:decimal
xs:integer
xs:boolean
xs:date
xs:time


B、例子:

简易元素定义:

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

引用简易类型的XML 元素:如:<lastname>元素,文本类型为 “字符串”
<lastname>Smith</lastname>
<age>28</age>
<dateborn>1980-03-27</dateborn>


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

A、定义属性的语法 :attrribute 关键字

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


在此处,xxx 指属性名称,yyy 则规定属性的数据类型。XML Schema 拥有很多内建的数据类型。
最常用的类型是:

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

B、例子

属性的定义:如,属性名为 lang 属性值的类型为字符串

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

XML 元素:

<lastname lang="EN">Smith</lastname>


C、属性的默认值(default)和固定值(fixed)

当没有其他的值被规定时,默认值就会自动分配给元素。在下面的例子中,缺省值是 "EN":

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

固定值同样会自动分配给元素,并且无法规定另外的值。在下面的例子中,固定值是 "EN":

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

D、可选的和必需的属性(use="required")

在缺省的情况下,属性是可选的。如需规定属性为必选,请使用 "use" 属性

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


③、限定:restriction

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

A、对值的限定:
下面的例子定义了带有一个限定且名为 "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> 


B、对一组值的限定:枚举enumeration
如需把 XML 元素的内容限制为一组可接受的值,我们要使用枚举约束(enumeration constraint)。
下面的例子定义了带有一个限定的名为 "car" 的元素。可接受的值只有:Audi,Golf,BMW:

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


上面的例子也可以被写为:这样可以达到通用的效果,在这种情况下,类型 "carType" 可被其他元素使用,因为它不是 "car" 元素的组成部分。

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


C、对一系列值的限定 正则pattern
如需把 XML 元素的内容限制定义为一系列可使用的数字或字母,我们要使用模式约束(pattern constraint)。
下面的例子定义了带有一个限定的名为 "letter" 的元素。可接受的值只有小写字母 a - z 其中的一个:

<xs:element name="letter">
	<xs:simpleType>
	  <xs:restriction base="xs:string">
		<xs:pattern value="[a-z]"/> //只有小写字母 a - z 其中的一个
	  </xs:restriction>
	</xs:simpleType>
</xs:element> 

D、对空白字符的限定whitespace
如需规定对空白字符(whitespace characters)的处理方式,我们需要使用 whiteSpace 限定。
下面的例子定义了带有一个限定的名为 "address" 的元素。

preserve,这意味着 XML 处理器不会移除任何空白字符。

replace,这意味着 XML 处理器将移除所有空白字符(换行、回车、空格以及制表符)。

collapse,这意味着 XML 处理器将移除所有空白字符(换行、回车、空格以及制表符会被替换为空格,开头和结尾的空格会被移除,而多个连续的空格会被缩减为一个单一的空格)。

<xs:element name="address">
	<xs:simpleType>
	  <xs:restriction base="xs:string">
		<xs:whiteSpace value="preserve"/>  //
		<xs:whiteSpace value="replace"/>
		<xs:whiteSpace value="collapse"/>
	  </xs:restriction>
	</xs:simpleType>
</xs:element> 


E、对长度的限定
如需限制元素中值的长度,我们需要使用 length、maxLength 以及 minLength 限定。

本例定义了带有一个限定且名为 "password" 的元素。其值必须精确到 8 个字符:

<xs:element name="password">
	<xs:simpleType>
	  <xs:restriction base="xs:string">
		<xs:length value="8"/>
	  </xs:restriction>
	</xs:simpleType>
</xs:element> 

这个例子也定义了带有一个限定的名为 "password" 的元素。其值最小为 5 个字符,最大为 8 个字符:

<xs:element name="password">
	<xs:simpleType>
	  <xs:restriction base="xs:string">
		<xs:minLength value="5"/>
		<xs:maxLength value="8"/>
	  </xs:restriction>
	</xs:simpleType>
</xs:element> 

F、数据类型的限定:



2)复杂的类型:——complexType

①、复合元素:

有两种方式来定义复合元素:如复合 XML 元素,"employee"。

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

A、通过命名此元素,可直接对"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>中。这意味着子元素必须以它们被声明的次序出现。


B、"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"/>

C、继承:可以在已有的复合元素之上以某个复合元素为基础(base、complexContent、extension),然后添加一些元素,就像这样:

<xs:complexType name="fullpersoninfo">
  <xs:complexContent>
    <span style="color:#ff0000;"><xs:extension base="personinfo"></span>
      <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>

②、复合空元素

A、

复合元素不能包含内容,只能含有属性。如,一个空的 XML 元素:

<product prodid="1345" />
上面的 "product" 元素根本没有内容。为了定义无内容的类型,我们就必须声明一个在其内容中只能包含元素的类型,但是实际上我们并不会声明任何元素,比如这样:

<xs:element name="product">
  <xs:complexType>
    <xs:complexContent>
      <xs:restriction base="xs:integer">
        <xs:attribute name="prodid" type="xs:positiveInteger"/>
      </xs:restriction>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

分析:complexContent 元素:我们打算限定或者拓展某个复合类型的内容模型,而 integer 限定则声明了一个属性但不会引入任何的元素内容

B、利用 type 的写法如下:

// 简单写法
<xs:element name="product">
  <xs:complexType>
    <xs:attribute name="prodid" type="xs:positiveInteger"/>
  </xs:complexType>
</xs:element>


// 使用 type 的写法
<xs:element name="product" type="prodtype"/>
	<xs:complexType name="prodtype">
	<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>


③、仅含元素

A、Xml文档:

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

B、Schema限定:

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

④、仅含文本-有属性和文本

使用simpleContent 元素。当使用简易内容时,我们就必须在 simpleContent 元素内定义扩展或限定

A、Xml文档:

<shoesize country="france">35</shoesize>

B、Schema限定:

<xs:element name="shoesize">
  <xs:complexType>
    <xs:simpleContent>
      <xs:extension base="xs:integer">
        <xs:attribute name="country" type="xs:string" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:element>
分析:声明了一个复合类型,其内容被定义为整数值,并且 "shoesize" 元素含有名为 "country" 的属性

⑤、混合内容

A、Xml文档:

<letter>
Dear Mr.<name>John Smith</name>.
Your order <orderid>1032</orderid>
will be shipped on <shipdate>2001-07-13</shipdate>.
</letter>

B、

<xs:element name="letter">
  <xs:complexType 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>
</xs:element>

分析:

为了使字符数据可以出现在 "letter" 的子元素之间,mixed 属性必须被设置为 "true"。
<xs:sequence> 标签 (name、orderid 以及 shipdate ) 意味着被定义的元素必须依次出现在 "letter" 元素内部。

⑥、指示器

通过指示器,我们可以控制在文档中使用元素的方式。有七种指示器(前五种常用):



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

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

<xs:element name="person">
  <xs:complexType>
    <span style="color:#3333ff;"><xs:all></span>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
 <span style="color:#3333ff;">   </xs:all></span>
  </xs:complexType>
</xs:element>


注释:

当使用 <all> 指示器时,你可以把 <minOccurs> 设置为 0 或者 1,而只能把 <maxOccurs> 指示器设置为 1

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

<xs:element name="person">
  <xs:complexType>
    <span style="color:#3333ff;"><xs:choice></span>
      <xs:element name="employee" type="employee"/>
      <xs:element name="member" type="member"/>
   <span style="background-color: rgb(51,51,255);"> </xs:choice></span>
  </xs:complexType>
</xs:element>
分析:<employee><member>两个元素, 非此即彼。

如需设置子元素出现任意次数,可将 <maxOccurs> (稍后会讲解)设置为 unbounded(无限次)。

Ⅲ、<sequence> 规定子元素必须按照特定的顺序出现:前面的例子很多。


B、Occurrence 指示器:用于定义某个元素出现的频率。

Ⅰ、<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> 指示器可规定某个元素能够出现的最小次数

<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" 这个声明:


3)实际例子:

①、Xml文档

<?xml version="1.0" encoding="ISO-8859-1"?>

<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="family.xsd">

<person>
<full_name>Tony Smith</full_name>
<child_name>Cecilie</child_name>
</person>

<person>
<full_name>David Smith</full_name>
<child_name>Jogn</child_name>
<child_name>mike</child_name>
<child_name>kyle</child_name>
<child_name>mary</child_name>
</person>

<person>
<full_name>Michael Smith</full_name>
</person>

</persons>


②、Schena限定:family.xsd

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">

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

</xs:schema>

猜你在找的XML相关文章