天天看點

XML與Schema,Schema的複用

在XML中使用Schema

Schema概述

與DTD相比Schema的優勢如下:

XML Schema是基于XML進行編寫

XML Schema支援資料類型

XML Schema支援命名空間

XML Schema建議規範中有兩個基礎的命名空間:

一個是用于Schema文檔的Schema URI,即http://www.w3.org/2001/XMLSchema。通常使用xs來代表該命名空間。

另一個用于XML文檔,即http://www.w3.org/2001/XMLSchema-instance,通常使用xsi來代表該命名空間。

Schema作用

XML Schema即模式。文檔通常以單獨的檔案形式存在,檔案擴充名為.xsd。其主要作用如下:

定義可出現在文檔中的元素

定義可出現在文檔中的屬性

定義哪個元素是子元素

定義子元素的次序

定義子元素的數目

定義元素是否為空,或者是否可包含文本

定義元素和屬性的資料類型

定義元素和屬性的預設值以及固定值

Schema的引用方法

當XML引入Schema時,根據XML文檔的元素是否屬于某個特定命名空間的,可以按照如下兩種方式引入:

不屬于特定的命名空間

通過屬性xsi:noNamespaceSchemaLocation引入

屬于某個特定的命名空間

通過屬性xsi:shemaLocation引入

如果Schema檔案要限制的XML檔案中的元素不屬于任何特定命名空間,使用xsi:noNamespaceSchemaLocation屬性引入。具體文法如下:

<根元素名稱 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Schema檔案路徑">

xsi:noNamespaceSchemaLocation :屬性值為一個Schema檔案的URI。
該屬性值隻能是一個Schema檔案URI,即隻能使用一個Schema檔案。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      

如果被引入的Schema檔案需要限制XML檔案中屬于某個任何特定的命名空間元素,則通過xsi:schemaLocation屬性引入。具體文法如下:

<根元素名稱 
[xmlns[:prefix]="命名空間URI"]+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="[命名空間URI  Schema檔案路徑]+">
+代表可以寫多個的意思

[xmlns[:prefix]="命名空間URI"]+ : 可選項。可以同時引入多個命名空間。
但必須是引用的Schema定義過的命名空間。另外可以給命名空間指明多個字首。

xsi:schemaLocation=“[命名空間URI  Schema檔案路徑]+” :該屬性值可以引入Schema檔案。
Schema的引入需要一個命名空間URI和Schema檔案路徑,
命名空間URI和Schema檔案路徑中間使用空格間隔。
命名空間URI需要與Schema檔案中TargetNamespace定義的一樣。      

Schema的文法結構

Schema是擴充名為”.xsd”的文本檔案,使用XML文法編寫。

運作.xsd的檔案路徑有中文可能會出錯。

<?xml version="1.0"?>
<xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema
targetNamespace="命名空間的URL"
[xmlns[:prefix]= "命名空間的URL"]
[elementFormDefault="qualified | unqualified"]
[attributeFormDefault="qualified | unqualified"]>
     元素、屬性、注釋、資料類型、schema的複用等的定義
</xs:schema>      
schema是每一個 XML Schema 的根元素。

xmlns:xs=http://www.w3.org/2001/XMLSchema表示schema文檔中用到的元素來自該命名空間。
同時它還規定了元素應該使用字首 xs:。比如<xs:element>,<xs:attribute>。

targetNamespace定義被此schema定義的XML文檔的元素和屬性的命名空間。

xmlns[:prefix]= "命名空間的URL",若要引用Schema文檔中的元素,必須聲明命名空間,
且URL為targetNamespace定義的命名空間。在該Schema文檔中和引用該Schema文檔的XML文檔中,
給命名空間指定的字首是獨立的。      
全局元素和局部元素以及全局屬性和局部屬性是根據元素或屬性定義的位置決定的。

在schema中,定義在schema元素下的元素或屬性稱為全局元素或全局屬性(即schema元素的子元素)。
    全局元素可以被引用,全局屬性必須被引用。

在schema中,定義在複雜類型中的元素或者屬性,稱之為局部元素或局部屬性。
    局部元素或局部屬性僅能在定義該元素或屬性的外部元素中使用。

elementFormDefault: 屬性值是qualified或unqualified,
          用于指定XML使用Schema中定義的局部元素是否使用命名空間限定。
          預設值為unqualified,表示不使用命名空間限定。
          
attributeFormDefault:      

注釋

注釋的具體方法包括兩種:
1. XML文法中的注釋<!-- 被注釋的内容-->。
2. 通過标記<annotation>來增加注釋,該方式具有更好的可讀性。
<annotation>:用于說明該Schema元件的作用。
      内部可以出現多個<documentation>和<appinfo>而且順序和次數沒有限制。
<documentation> :該子元素的注釋主要供人來閱讀使用。
<appinfo>:該子元素的注釋主要供其它程式來使用。      

Schema中定義元素的文法主要包括以下三類:

文法1:
<xs:element name="元素名稱"  type="資料類型"  [default="預設值"] | [fixed="固定值"] [minOccurs="最少出現的次數"]  [maxOccurs="最多出現的次數"]/>
例如:  
<xs:element name="to"  type="xs:string"  minOccurs="0"/>      
文法1:
<xs:element name="元素名稱"  type="資料類型"  [default="預設值"] | [fixed="固定值"] [minOccurs="最少出現的次數"]  [maxOccurs="最多出現的次數"]/>
例如:  
<xs:element name="to"  type="xs:string"  minOccurs="0"/>      

例如

XML與Schema,Schema的複用
文法3:
<xs:element ref="引用元素名稱" [default="預設值"]|[fixed="固定值"] [minOccurs="最少出現的次數"]  [maxOccurs="最多出現的次數"]/>

<xs:element name="root">
  <xs:complexType>
    <xs:element ref="sub" minOccurs="1" maxOccurs="unbounded"/>
  </xs:complexType>
</xs:element>
<xs:element name="sub" type="xs:string"/>      
屬性說明:
name : 由程式員指定,元素的名字
type : 元素類型
ref  : 引用的元素名稱。
default:元素的預設值,可選(不能與fixed屬性同時存在)
fixed:元素的固定值,可選(不能與default屬性同時存在)
minOccurs : 元素出現的最少次數,預設值為1,可選。
    屬性值為0則表示該元素是可選的。
    minOccurs與maxOccurs不同時出現時,則該屬性值隻能為0或1。
    
maxOccurs : 元素出現的最大次數,預設值為1,可選。
      屬性值為“unbounded”時,指定元素可以出現任意多次。
      minOccurs與maxOccurs不同時出現時,則該屬性值大于0。      

定義屬性的文法格式如下所示:

文法1:
<xs:attribute  name="屬性名"  type="屬性類型"
[default="預設值"] | [fixed="固定值"]  use="使用限制">
</xs:attribute>
文法2:
<xs:attribute ref="屬性名"  use="使用限制">
</xs:attribute>
注意:隻有在複雜類型complexType中才能定義屬性!

屬性說明如下:
name:XML元素的屬性名
type:屬性的資料類型。
use:      

Schema的資料類型

有一點需要特别注意的是,Schema的資料類型定義,隻是在邏輯上對XML文本文檔的内容進行了限制,并不對應一個實際的變量。比如把一個元素的内容定義為int型,表示的是,元素的文本内容隻能是整數,不能是字元串等其它内容。但本質上,該内容是一個内容為整數的文本。

Schema的資料類型有很多作用,比如可保護資料通信。當資料從發送方被發送到接受方時,其要點是雙方應有關于内容的相同的“期望值”。通過 XML Schema,發送方可以用一種接受方能夠明白的方式來描述資料。一種資料,比如 “03-11-2004”,在某些國家被解釋為11月3日,而在另一些國家為當作3月11日。但是一個帶有資料類型的 XML 元素,比如:< date type=“date”>2004-03-11</ date>,可確定對内容一緻的了解,這是因為 XML 的資料類型 “date” 要求的格式是 “YYYY-MM-DD”。

Schema的資料類型根據該元素内容可劃分為簡單類型和複雜類型。

簡單類型指元素的内容中即不包括子元素也不包括屬性。

複雜類型指元素的内容中包括子元素或屬性。

Schema的資料類型按照擴充方式可以分為:

内置資料類型

使用者自定義類型

内置資料類型

内置資料類型是被預先定義好的,這些資料類型全部位于命名空間http://www.w3.org/2001/XMLSchema下,所有的内置資料類型都是簡單類型。

在W3C的官方網站上,描述了所有内置資料類型的繼承關系。在Schema中,資料類型A繼承資料類型B,實際上可以了解為資料類型A是在資料類型B的基礎上做restriction(限制)操作得到的,即A的value space(取值範圍)是B的value space的子集。

内置類型分為3個部分:

任意類型

内置基本資料類型

内置擴充資料類型

任意類型

任意類型包括兩種:

anyType:表示該元素為任意類型,與DTD的ANY類似。此類型對于元素的内容沒有任何限制。

anySimpleType:表示該元素為任意簡單類型。即定義為該類型的元素除不能包含子元素和屬性外,沒有任何其它的限制。

内置基本資料類型

字元串類型
string 表示字元串,原封不動保留所有空白
QName 表示一個包含在XML命名空間在内的合法名稱(命名空間可省略)
數值類型
decimal 數字
float 單精度32位浮點數
double 雙精度64位浮點數
base64Binary 任意base64編碼的二進制數
hexBinary 任意16進制編碼的二進制數
日期類型
date 日期YYYY-MM-DD格式的時間
gYearMonth 年月YYYY-MM格式的時間
gYear 年YYYY格式的時間
gMonthDay 月日- -MM-DD格式的時間
gDay 日期—DD格式的時間
gMonth 月份–MM格式的時間
時間類型
duration 表示持續時間PnYnMnDTnHnMnS,P起始定界符,T分隔符,s前面的n可以是小數
dateTime 表示時間,YYYY-MM-DDThh:mm:ss:sss,sss表示毫秒數
time 表示時間,hh:mm:ss:sss,sss表示毫秒數
Boolean類型
boolean 布爾型,隻能接受true,false,0,1
anyURI類型
anyURI 表示一個URI,用來定位檔案
Notation類型
NOTATION 表示XML中的NOTAITION類型,不能在模式中直接出現的抽象類型,隻能用于派生其它類型。

内置擴充資料類型

String類型派生出來的類型及其描述
normalizedString 将字元串的換行、制表符和回車符替換為空格
token 換行、制表符和回車符替換為空格,且字元串前後空白自動删除;中間多個連續的空白替換為單個空白
language 定義合法的語言代碼
Name 含有一個有效的XML名稱的字元串
NCName 省略或不帶有命名空間字首的XML名稱字元串,不含冒号
String類型派生出來用于限制屬性的類型及其描述
NMTOKEN 必須是合法的XML名稱,隻能由字母、數字、“_”、“-”、“.”、“:”組成
NMTOKENS 多個NMTOKEN,空格為分隔符
ID 辨別符
IDREF 引用另一個ID
IDREFS 引用多個已有的ID,空格為分隔符
ENTITY 外部實體
ENTITIES 多個外部實體,空格為分隔符

decimal類型派生出來的類型及其描述

XML與Schema,Schema的複用

|

XML與Schema,Schema的複用

使用者自定義類型

使用者自定義類型按位置可以分為全局類型和局部類型。

全局類型是直接在schema标記内定義的類型,該類型可以被所有元素使用。

局部類型是定義在某個元素内部的類型,該類型隻能被定義該類型的元素所引用

使用者自定義類型還可以按照複雜程度劃分,分為簡單類型和複雜類型。

自定義簡單資料類型

自定義簡單類型是在内置資料類型的基礎上通過限制、清單和聯合中一種或幾種方式形成的新資料類型。簡單資料類型的定義文法:

<xs:simpleType [name="自定義類型名稱"]>
[限制、清單、聯合一種或幾種方式]
</xs:simpleType>
name屬性:自定義的資料類型名稱。當定義的簡單資料類型為全局資料類型,
    即直接在<schema>标記中定義,必須寫出該屬性。
    如果為局部資料類型,則沒有該屬性。      
限制
如果通過限制方式産生自定義類型,需要使用的标記為restriction。文法格式如下:
<xs:simpleType [name="自定義類型名稱"]>
  <xs:restriction base="基類型" >
    [限制特征]+
  </xs:restriction>
</xs:simpleType>      
XML與Schema,Schema的複用
清單
Schema中定義清單類型使用<list.../>元素,
它把單個簡單資料類型擴充出清單類型,
是以使用該元素時必須指出清單元素的類型,
為<list/>元素指定清單元素類型有兩種方式。
1是通過為<list.../>元素的itemType屬性指定清單元素。
2是為<list.../>元素增加<simpleType.../>子元素來指定清單元素的資料類型。

為<list.../>元素的itemType屬性指定清單元素的資料類型
<xs:simpleType [name="自定義類型名稱"]>
  <xs:list itemType="清單資料類型" ></xs:list >
</xs:simpleType>

為<list.../>元素增加<simpleType.../>子元素來指定清單元素的資料類型:
<xs:simpleType [name="自定義類型名稱"]>
  <xs:list>
             <simpleType.../>
  </xs:list >
</xs:simpleType>      
聯合
Schema中聯合類型使用<union.../>元素,
它把單個簡單資料類型擴充出聯合類型。
為<union.../>元素指定聯合元素類型有兩種方式。
1是通過為<union.../>元素的memeberTypes屬性指定清單元素。
2是為<union.../>元素增加一個或多個<simpleType.../>子元素,每個<simpleType.../>子元素指定一個簡單資料類型。

為<union.../>元素的memberTypes屬性指定一個或多個簡單類型,多個簡單類型之間以空格隔開。
<xs:simpleType [name="自定義類型名稱"]>
  <xs:union memberTypes="[清單資料類型]+" ></xs:union>
</xs:simpleType>

為<union.../>元素增加一個或多個<simpleType.../>子元素,每個<simpleType.../>子元素指定一個簡單類型。
<xs:simpleType [name="自定義類型名稱"]>
  <xs:union>
             [<simpleType.../>]+
  </xs:union>
</xs:simpleType>      

混合内容

複雜類型所限制的内容可能包含屬性、子元素或同時包含子元素和屬性。複雜元素也有可能在包含子元素的同時還包含字元内容,這樣的元素被稱為混合内容。定義複雜元素的文法格式如下所示:

<xs:complexType [name="自定義類型名稱"] [mixed="true|false"]>
  [順序、選擇、無序、簡單内容、複雜内容]+
</xs:complexType>

name屬性:資料類型名稱。當定義的簡單資料類型為全局資料類型,
    必須寫出該屬性。如果為局部資料類型,則沒有該屬性。
mixed屬性:如果mixed屬性值設定為true,則表示該元素的内容為混合内容。
      該屬性預設值為false。      
順序<xs:sequence>
使用該元素定義的資料類型用于設定子元素的順序,表示該元素的子元素是有序的。
使用該元素的文法格式如下:
<xs:complexType name="自定義類型名稱">
  <xs:sequence [maxOccurs="最多出現的次數"] [minOccurs="最少出現的次數"]>
    定義元素[<xs:element>]+
  </xs:sequence>
</xs:complexType>

選擇<xs:choice>
使用該元素定義的資料類型用于設定子元素的選擇關系,
表示該元素的子元素可以根據實際需要從子元素中選擇一個使用。使用該元素的文法格式如下:
<xs:complexType name="自定義類型名稱">
  <xs:choice [maxOccurs="最多出現的次數"] [minOccurs="最少出現的次數"]>
    定義元素[<xs:element>]+
  </xs:choice>
</xs:complexType>

無序<xs:all>
使用<xs:all>元素定義的資料類型用于設定子元素可以按照任意順序出現,且每個子元素必須隻出現一次。
該元素設定子元素不能增加屬性;不能與<xs:sequence>或<xs:choice>同時出現。
使用該元素的文法格式如下:
<xs:complexType name="自定義類型名稱">
  <xs:all minOccurs="0|1" maxOccurs="1">
    定義元素[<xs:element>]+
  </xs:all>
</xs:complexType>      

簡單内容< simpleContent/>

如果元素隻包含屬性,不包含子元素,則可以使用該元素定義元素内容。

具體的内容方式包括在基類型上擴充和限制兩種方式:

限制<xs:restriction base="基類型"></xs:restriction> :
基類型必須為一個僅包含屬性的簡單類型。
該标記中可以嵌套基于restriction元素内的所有特征元素,對目前的基類型進行限制。

擴充<xs:extension base="基類型"></xs:extension>      

複雜内容< complexContent/>

如果元素包含子元素(是否包含屬性不限制),則可以使用該元素對元素内容進行定義。

限制<xs:restriction base="基類型"></xs:restriction>:
基類型為一個已經定義好的複雜資料類型,在基類型的基礎上增加限制。

擴充<xs:extension base="基類型"></xs:extension>:
基類型為一個已經定義好的複雜資料類型。在基類型的基礎上擴充,
可以既可以增加子元素,也可以增加屬性。      

Schema的元素替換

XML Schema提供了一種機制叫置換組。當元素定義為全局元素時,允許使用substitutionGroup屬性,包含substitutionGroup屬性的元素被稱為替換元素,屬性的值為定義好的元素。替換元素允許被替換為被指定的定義好的元素。substitutionGroup屬性指定的元素稱為被替換元素,也叫頭元素(Head Element),

需要注意的是:

替換元素與頭元素(被替換元素)都必須是全局元素。

替換元素與頭元素必須具有相同的資料類型,或者替換元素的類型是從非替換元素派生出來的。

當定義了替換元素之後,并非意味着不能使用頭元素,它隻是提供了一個允許元素可替換使用的機制。

抽象元素和抽象類型

當一個元素被聲明為“abstract”時,那麼該元素為抽象元素。

當一個類型被聲明為“abstract”時,那麼該類型為抽象類型。

抽象元素和抽象類型不能直接使用,必須有元素和類型對它們進行派生。使用抽象類型時,XML文檔隻能使用xsi:type屬性指定抽象類型的派生類型。

限制替換元素和限制派生類型

當元素或者自定義複雜類型包含final屬性時,表示元素或該類型限制派生。final屬性值指定限制的方式:

#all:阻止以任何方式派生

extension:阻止以擴充方式派生

restriction:阻止以限制方式派生

extension和restriction:阻止同時以擴充方式和限制方式派生

限制替換類型

限制替換還可以對某個特定複雜類型進行限制,此時複雜類型的定義中< complexType>元素使用block屬性。當某個特定類型增加限制時,表示使用該類型的元素被替換時,應該遵循類型中的限制。具體的限制方式依據block的屬性值,具體指定限制的方式包括:

元素和屬性的限制

key、unique和keyref标記的含義:
key限制:要求所限制的内容必須存在并保證唯一性;
unique限制:要求内容必須唯一,但可以不存在;
keyref限制:要求該内容必須引用一個key限制或unique限制的值。

<xs:key|unique|keyref name="限制名" [refer="參考的限制名"]>
  <xs:selector xpath="指定的範圍"/>
  <xs:field xpath="指定的元素或屬性"/>
</xs:key>      

Schema的複用

使用include元素将另一份Schema包含到目前的Schema中要求如下:
被包含的Schema檔案可以不屬于任何命名空間,
但如果包含命名空間,該命名空間必須與包含檔案的命名空間保持一緻。
使用include元素的文法格式為:
<include schemaLocation=”被包含的Schema的檔案”/>      
redefine元素可以實作Schema的複用。
可以把redefine元素當成include的增強版,
redefine包含Schema檔案還允許重新定義被包含的Schema元件。
文法格式為:
<redefine schemaLocation=”被包含的Schema的檔案”/>

需要注意:
重定義的元件必須是Schema裡已有的元件;
重定義的元件隻能對被包含在Schema裡已有的元件增加限制或增加擴充;
如果采用增加限制的方式來重定義原有的元件,則<restriction.../>元素裡所包含的限制不能違反原類型已有的限制。      
<import.../>元素專門用于複用不同命名空間的。
使用<import.../>元素導入另一份Schema,要求被導入的Schema檔案必須與目前檔案定義不同的命名空間。
使用該元素的文法:
<import schemaLocation="被包含的Schema的檔案" [namespace="被包含的Schema的檔案的命名空間"]/>      

Schema空元素表示

空元素的定義方法具體包括兩種:
minOccurs="0" 元素:
如果是為空值的複雜類型,并且希望它占用最小的空間,
則使用 minOccurs="0" 元素;

nillable="true" 元素:如果空值必須有占位符(例如當其在數組中出現時),
則使用 nillable="true" 元素。
注意nillabe屬性值隻能為true或false,
用于指定是否可以将顯示的零值配置設定給該元素,該屬性隻對元素内容有效,
而對元素屬性無效。屬性的預設值為false。      

繼續閱讀