原文:http://www.cnblogs.com/kissdodog/archive/2013/02/25/2931941.htmljavascript
驗證XML文檔是否符合議定的XML結構有兩種方法,分別是DTD模式與XML Schema。本文主要介紹XML Schema。html
XSD文檔至少要包含:schema根元素和XML模式命名空間的定義、元素定義。須要注意的是XSD中必須定義一個且只能定義一個schema根元素,根元素中包括模式的約束,XML模式命名空間的定義,其餘命名空間的定義、版本信息、語言信息和其餘一些信息。java
一、schema根元素git
語法以下:正則表達式
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> ... </xsd:schema>
二、元素架構
語法以下:工具
<xsd:element name="user" type="xsd:string" />
XSD中元素是利用element標識符來聲明,在上面的示例中name屬性是元素的名字,type屬性是元素值的類型,可使XML Schema中內置的數據類型或其餘類型。ui
所有元素以下:spa
元素 | 說明 |
name | 元素的名稱 |
type | 元素值的類型 |
minOccurs | 該元素在父元素中最少出現的次數(默認爲1,必須大於等於0) |
maxOccurs | 該元素在父元素中最多出現的次數(默認爲1,必須大於等於0),當設置爲unbounded表示不限制。 |
三、引用元素設計
引用元素是利用element標記符的ref屬性實現的。主要適用於避免在文檔中屢次定義同一個元素。表示當前元素與被引用的元素相同。
語法以下:
<xsd:element name="user" type="xsd:string" /> <xsd:sequence> <xsd:element ref="user" /> <!--當前元素就是user元素--> </xsd:sequence>
四、別名
別名主要利用element標識符中的屬性substitutionGroup實現的。
語法:
<xsd:element name="user" type="xsd:string" substitutionGroup="yonghu" />
該語句表示該行的元素名能夠是user或用戶,如:
<yonghu>admin</yonghu> <user>admin</user>
這兩行xml都是符合條件的。
五、設置默認值與固定值
語法以下:
<xsd:element name="city" type="xsd:string" default="xian" /> <xsd:element name="country" type="xsd:string" fixed="china" />
經過default屬性的設置,能夠在XML文檔中沒有對city定義時賦予默認值,而是用fixed屬性,能夠給元素country設定一個固定的值china,而且不容許改變。
六、利用組合器控制結構
一、sequence組合器,定義了一列元素必須按照模式中指定的順序顯示(若是是可選的,也能夠不顯示)。
<xsd:sequence> <xsd:element name="first" type="xsd:string" /> <xsd:element name="middle" type="xsd:string" /> <xsd:element name="last" type="xsd:string" /> </xsd:sequence>
二、all組合器,容許所定義的元素能夠按照任意順序顯示,all元素的子元素在默認狀況下士必須的,並且每次最多顯示一次。
<xsd:all minOccurs="0"> <xsd:element name="first" type="xsd:string" /> <xsd:element name="middle" type="xsd:string" /> <xsd:element name="last" type="xsd:string" /> </xsd:all>
(3)choice組合器,容許指定多組聲明中的一個,用於互斥狀況。
<xsd:choice> <xsd:element name="first" type="xsd:string" /> <xsd:element name="middle" type="xsd:string" /> <xsd:element name="last" type="xsd:string" /> </xsd:choice>
七、定義屬性
在XML Schema文檔中能夠按照定義元素的方法定義屬性,但受限制程度較高。能夠應用在attribute元素定義中的屬性以下表所示。
屬性 | 含義 |
defalt | 初始默認值 |
fixed | 不能修改和覆蓋的固定屬性值 |
name | 屬性的名稱 |
ref | 對前一個屬性定義的引用 |
type | 該屬性的XSD類型或者簡單類型 |
use | 如何使用屬性 optional(可選屬性,即屬性不是必須的,默認是這個)、prohibited(禁止使用)或者required(強制必須)。 |
form | 肯定attributeFormDefault的本地址 |
id | 模式文檔中屬性惟一的ID |
八、建立屬性
語法以下:
<xsd:attribute name="age" type="xsd:integer" />
該語句定義了一個名爲age的屬性,它的值必須爲整數。把它添加到模式中時,它必須是schema元素,complexType元素或者attributeGroup元素的子元素。
代碼示例:
<xsd:element name="name"> <xsd:complexType> <xsd:sequence> <xsd:element name="first" type="xsd:string" /> </xsd:sequence> <xsd:attribute name="age" type="xsd:integer" use="optional" /> <!--將屬性添加到元素name屬性中--> </xsd:complexType> </xsd:element>
以上文檔對應有效的XML文檔以下:
<?xml version="1.0"?> <name age="27"> <first>string</first> </name>
該示例不但說明了以下約束屬性,還展現了組合器的用法。
一、Schema基本數據類型
Schema的基本數據類型以下:
數據類型 | 說明 |
boolean | true/false |
datetime | 格式:CCYY-MM-DDThh:mm:ss |
decimal | 任意精度的十進制數字 |
string | 字符串數據 |
int | 整型 |
nonNegativeInteger | 大於或等於0的整型 |
nonPositiveInteger | 小於或等於0的整型 |
short | 短整型 -32768到32767 |
二、約束
內置的數據類型功能雖然已經有必定的限制功能,可是仍是遠遠不足夠的,更進一步的約束仍是來看看約束。
約束 | 說明 |
enumeration | 用空格分開的一組指定的數值,它把數據類型約束爲指定的值 |
fractionDigit | 指定小數點後的最大位數 |
length | 長度單位 |
minExclusive | 下限值 |
maxExclusive | 上限值 |
minLength | 最小長度單位 |
maxLength | 最大長度單位 |
minInclusive | 最小值,全部的值都應該大於或等於該值 |
maxInclusive | 最大值,全部的值都應該小於或等於該值 |
pattern | 數據類型的值必須匹配的指定模式,必須是一個正則表達式 |
totalDigits | 指定小數最大位數的值 |
whiteSpace | 其值爲preserve(值中的空格不能改變)、replace(全部的製表符、換行符、回車符都用空格代替)、collapse(執行replace,刪除相鄰的、結尾處和開頭處的空格)。 |
要使用上面約束表的約束,就要利用元素restriction。這個元素中有兩個屬性:ID屬性是模式文檔中restriction元素的位置標識符;base屬性設置爲一個內置的XSD數據類型或者現有的簡單類型定義,它是一種被限制的類型。
示例:將一個整數的取值範圍設置爲1~100之間。
<xsd:restriction base="xsd:int"> <xsd:minInclusive value="1" /> <xsd:maxInclusive value="100" /> </xsd:restriction>
三、簡單類型
簡單類型是對一個節點的可能值進一步限制的自定義數據類型。建立簡單類型須要利用simpleType元素,其定義以下:
<simpleType id="ID" name="NCName" final="(#all|((list|union|restriction)))" />
ID屬性應惟一地標明文檔內的simpleType元素,name不能使用冒號字符。simpleType不能包含元素,也不能有屬性,它基本上是一個值,或者是一個值的集合。
例如:
<xsd:simpleType name="USState"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="AK"> <xsd:enumeration value="AL"> <xsd:enumeration value="AR"> </xsd:restriction> </xsd:simpleType> <xsd:element name="statement" type="USState" />
以上文檔對應有效的xml文檔以下:
<statement>AK</statement>
注意取值只可以爲AK、AR、AL中的一個。
四、列表類型
list能夠用來定義列表類型。
<xsd:simpleType name="listOfIntType"> <xsd:list itemType="Integer"/> </xsd:simpleType> <xsd:element name="listOfMyInt" type="listOfType"/>
listIfIntType這個類型被定義爲一個Integet的列表,元素listOfMyInt的值能夠是幾個整數,他們之間用空格分開。
有效的xml文檔以下:
<listOfMyInt>1 2 3 123</listOfMyInt>
五、聯合類型
union能夠用來定義一個聯合類型。例如:
<xsd:simpleType name="zipUnion"> <xsd:union memberTypes="USState listOfMyIntType"/> </xsd:simpleType> <xsd:element name="zips" type="zipUnion"/>
用union來定義一個聯合類型,裏面的成員類型保羅USState和listOfMyIntType,應用了聯合類型的元素的值能夠是這些原子類型或列表類型中的一個類型的示例,可是一個元素實例不能同時包含兩個類型。
有效的XML文檔以下:
<zips>CA</zips> <zips>9192 192391 129</zips> <zips>AK</zips>
無效的XML文檔以下:
<zips>AL 2231</zips>
同時包含兩個是錯誤的。
六、匿名類型
前面定義元素類型的時候老是先定義一個數據類型,而後再把元素的type設成新定義的數據類型。若是這個新的數據類型只會用一次,咱們就能夠直接設置在元素定義裏面,而不用另外來設置。
例如:
<xsd:element name="quantity"> <xsd:simpleType> <xsd:restriction base="xsd:positiveInteger"> <xsd:maxExclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:element>
元素quantity的類型就是一個從1~99的整數。對於這種沒有用type引入,直接定義在element元素裏面的類型,咱們稱之爲匿名類型。
七、複雜類型
複雜類型的定義必須使用complexType元素,在這裏能夠包含屬性和元素。在複雜類型的使用中,主要是complexType和simpleType配合使用。
八、內容模型
內容模型能夠對在XML文檔內使用的元素、屬性和類型進行限制,肯定用戶能夠再XML實例的那些等級添加本身的元素和屬性。
一、any內容模型
在XML中聲明元素時,any是默認的內容模型,該模型能夠包含文本、元素和空格。
例如:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="name"> <xsd:complexType> <xsd:sequence> <xsd:element name="first" type="xsd:string" /> <xsd:element name="middle" type="OtherNames" /> <xsd:element name="last" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:complexType name="OtherNames"> <xsd:sequence> <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> </xsd:schema>
例子中xsd:any元素說明該類型容許添加內容。
namespace屬性容許的值爲:
processContents屬性說明對這裏所建立的元素進行驗證時所執行的操做。
processContents屬性取值有以下三種:
上述模式的一個有效實例:
<?xml version="1.0" encoding="utf-8" ?> <name> <first>santld</first> <middle> <nameInChina>San</nameInChina> </middle> <last>wang</last> </name>
二、空內容模型(empty)
有時候元素根本沒有內容,它的內容模型是空。爲了定義內容是空的類型,咱們能夠經過這樣的方式:首先定義一個元素,它只能包含子元素而不能包含元素內容,而後又不定義任何子元素,依靠這樣的方式,就可以定義出內容模型爲空的元素。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="internationalPrice"> <xsd:complexType> <xsd:complexContent> <xsd:restriction base="xsd:anyType"> <xsd:attribute name="currency" type="xsd:string"/> <xsd:attribute name="value" type="xsd:decimal"/> </xsd:restriction> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>
有效的XML文檔以下:
<internationalPrice currency="ERU" value="/423.46"/>
無效的文檔示例:
<internationalPrice currency="ERU" value="/423.46"/>這是錯誤的</internationalPrice>
三、混合內容模型(mixed)
它包含文本、內容和屬性。在complexType元素上把mixed屬性的值設爲true,就聲明瞭一個mixed內容模型。例如:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="contact"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="first" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>
上述模式的一個有效實例以下:
<?xml version="1.0" encoding="utf-8" ?> <contact> My first is <first>Santld</first>. </contact>
用Visual Studio建立XSD Schema仍是較爲容易的。由於IDE提供可視化工具用於構建元素、簡單類型和複雜類型等。首先添加一個新的Schema文件。
英文版的名字是XML Schema,中文版是XML 架構。很奇怪,按照書上說的,添加一個XML Schema文件以後,工具箱會有不少工具,可是個人Visual Studio 2010裏面並無添加任何工具。此處留到之後再補充。
爲了在XML文檔中關聯外部的 XSD Schema文件,要對XML文檔以及XSD Schema文件做出相應的修改,具體的修改以下示例所示:
XML文件:
<?xml version="1.0" encoding="utf-8" ?> <person xmlns="http://www.xxx.com/xxx"> <name>張飛1111111</name> <age>24</age> </person>
XML Schema文件:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.xxx.com/xxx"> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="name"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="4"/> <xs:minLength value="2"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="age"> <xs:simpleType> <xs:restriction base="xs:positiveInteger"> <xs:maxExclusive value="100"/> <xs:minExclusive value="1"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
代碼文件:XmlDocument驗證文件
static void Main(string[] args) { XmlDocument doc = new XmlDocument(); //建立文檔 doc.Schemas.Add(null, @"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\person.xsd"); //添加驗證架構文件,null爲使用默認的命名空間 doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\person.xml"); //加載xml文件 doc.Validate(SettingsValidationEventHandler); //執行驗證操做,錯誤處理方法爲參數SettingsValidationEventHandler Console.WriteLine("驗證經過"); //若是驗證經過纔會執行到此 Console.ReadKey(); } static void SettingsValidationEventHandler(object sender, ValidationEventArgs e) { if (e.Severity == XmlSeverityType.Warning) { Console.Write("警告信息: "); Console.WriteLine(e.Message); } else if (e.Severity == XmlSeverityType.Error) { Console.Write("錯誤信息: "); Console.WriteLine(e.Message); } else { } Console.ReadKey(); }
代碼文件:XmlReader版本:
static void Main(string[] args) { XmlReaderSettings Settings = new XmlReaderSettings(); // Settings.Schemas.Add(null, @"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\person.xsd"); Settings.ValidationType = ValidationType.Schema; Settings.ValidationEventHandler += new ValidationEventHandler(SettingsValidationEventHandler); XmlReader reader = XmlReader.Create(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\person.xml", Settings); while (reader.Read()) { } reader.Close(); Console.WriteLine("驗證成功!"); Console.ReadKey(); } static void SettingsValidationEventHandler(object sender, ValidationEventArgs e) { if (e.Severity == XmlSeverityType.Warning) { Console.Write("警告信息: "); Console.WriteLine(e.Message); } else if (e.Severity == XmlSeverityType.Error) { Console.Write("錯誤信息: "); Console.WriteLine(e.Message); } else { } Console.ReadKey(); }