XML Schema 語言也稱作 XML Schema 定義(XML Schema Definition,XSD),作用是定義 XML 文檔的合法構建模塊,類似 DTD,但更加強大。
作用有:
①定義可出現在文檔中的元素
②定義可出現在文檔中的屬性
③定義哪個元素是子元素
④定義子元素的次序
⑤定義子元素的數目
⑥定義元素是否為空,或者是否可包含文本
⑦定義元素和屬性的數據類型
⑧定義元素和屬性的默認值以及固定值
XSD元素可分為簡單元素和復雜元素。
一、簡單元素
簡易元素指僅包含文本的元素,它不會包含任何其他的元素或屬性。
例如XML文檔:
<Name>張三</Name>
用XSD可寫為
<xs:element name="Name" type="xs:string"/>
此處“Name”是元素的名稱,“xs:string”是XML Schema內建的數據類型。
最常用的類型有:xs:string、xs:decimal、xs:integer、xs:boolean、xs:date、xs:time等。
如果要指定元素的默認值或固定值,默認值用default定義,固定值用fixed定義。
<xs:element name="Name" type="xs:string" default="張三"/>
<xs:element name="Name" type="xs:string" fixed="張三"/>
也可限定元素的取值范圍,例如限定字符串的長度為2至4,則可寫為如下:
<xs:element name="Name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="2" />
<xs:maxLength value="4" />
</xs:restriction>
</xs:simpleType>
</xs:element>
也可以寫成:
<xs:element name="Name" type="tns:T_Name" />
<xs:simpleType name="T_Name">
<xs:restriction base="xs:string">
<xs:minLength value="2" />
<xs:maxLength value="4" />
</xs:restriction>
</xs:simpleType>
二、復合元素
復合元素包含了其他的元素及/或屬性。
有四種類型的復合元素:
①空元素
②包含其他元素的元素
③僅包含文本的元素
④包含元素和文本的元素
一個XML代碼:
<Person id="1">
<Name>張三</Name>
<Age>120</Age>
</Person>
在 XML Schema 中,可定義為:
<xs:element name="Person" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Age" type="xs:string" />
</xs:sequence>
<xs:attribute name="id" type="xs:int" use="required" />
</xs:complexType>
</xs:element>
一些用法說明:
1、maxOccurs="unbounded"
maxOccurs為Occurrence 指示器,Occurrence 指示器用於定義某個元素出現的頻率,有2種類型分別是 maxOccurs和minOccurs ,默認值均為 1。
① maxOccurs 指示器:規定某個元素可出現的最大次數
如<xs:element name="Name" type="xs:string" maxOccurs="10"/>
規定元素“Name”最少出現一次(其中 minOccurs 的默認值是 1),最多出現 10 次。
② minOccurs 指示器:規定某個元素能夠出現的最小次數
如<xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="10"/>
規定元素“Name”最少出現0次,最多出現 10 次。
提示:如需使某個元素的出現次數不受限制,使用 maxOccurs="unbounded" 這個聲明
上面<xs:element name="Person" maxOccurs="unbounded">表示元素“Person”出現次數最少一次(其中 minOccurs 的默認值是 1),並且任意次數。
2、<xs:sequence>
<xs:sequence>為“Order 指示器”,Order 指示器用於定義元素的順序,有3種類型分別是All、Choice、Sequence。
① all 指示器:規定子元素可以按照任意順序出現
② Choice 指示器:規定可出現某個子元素或者可出現另外一個子元素(非此即彼)
③ Sequence 指示器:規定子元素必須按照特定的順序出現
上面例子代碼用<xs:sequence>規定了子元素“Name”和“Age”必須按順序出現。
3、use="required"
use 指示如何使用屬性,有3種:
① optional :屬性是可選的並且可以具有任何值。這是默認設置。
<xs:attribute name="id" type="xs:int"/>等價於
<xs:attribute name="id" type="xs:int" use="optional"/>
可驗證通過<Person>或<Person id="1">
② required :屬性必須出現一次。
<xs:attribute name="id" type="xs:int" use="required"/>
可驗證通過<Person id="1">
③ prohibited :不能使用屬性。
<xs:attribute name="id" use="prohibited"/>
規定了不能使用id的屬性。
實例1(無命名空間):
Persons.xml
<?xml version="1.0" encoding="UTF-8"?>
<Persons>
<Person id="1">
<Name>張三</Name>
<Age>120</Age>
</Person>
<Person id="2">
<Name>李四</Name>
<Age>20</Age>
</Person>
</Persons>
Persons.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:annotation>
<xs:documentation> 本文檔定義Persons.xml的格式 </xs:documentation>
</xs:annotation>
<xs:element name="Persons">
<xs:complexType>
<xs:sequence>
<xs:element name="Person" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="2" />
<xs:maxLength value="4" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Age">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[1-9][0-9]?|1[01][0-9]|120" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" use="required">
<xs:simpleType>
<xs:restriction base="xs:int"></xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
實例2(有命名空間):
Persons2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.xxx.com/XxxSystem">
<Person id="1">
<Name>張三</Name>
<Age>120</Age>
</Person>
<Person id="2">
<Name>李四</Name>
<Age>20</Age>
</Person>
</Persons>
Persons2.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.xxx.com/XxxSystem" >
<xs:annotation>
<xs:documentation> 本文檔定義Persons.xml的格式 </xs:documentation>
</xs:annotation>
<xs:annotation>
<xs:documentation>姓名</xs:documentation>
</xs:annotation>
<xs:simpleType name="T_Name">
<xs:restriction base="xs:string">
<xs:minLength value="2" />
<xs:maxLength value="4" />
</xs:restriction>
</xs:simpleType>
<xs:annotation>
<xs:documentation>年齡</xs:documentation>
</xs:annotation>
<xs:simpleType name="T_Age">
<xs:restriction base="xs:string">
<xs:pattern value="[1-9][0-9]?|1[01][0-9]|120" />
</xs:restriction>
</xs:simpleType>
<xs:annotation>
<xs:documentation>屬性ID</xs:documentation>
</xs:annotation>
<xs:simpleType name="T_id">
<xs:restriction base="xs:int"></xs:restriction>
</xs:simpleType>
<xs:element name="Persons">
<xs:complexType>
<xs:sequence>
<xs:element name="Person" maxOccurs="unbounded" type="tns:T_Person"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="T_Person">
<xs:sequence>
<xs:element name="Name" type="tns:T_Name" />
<xs:element name="Age" type="tns:T_Age" />
</xs:sequence>
<xs:attribute name="id" type="tns:T_id" use="required" />
</xs:complexType>
</xs:schema>
C# 使用xsd文件驗證XML格式
/// <summary>
/// 通過xsd驗證xml格式是否正確,正確返回空字符串,錯誤返回提示
/// </summary>
/// <param name="xmlFile">xml文件</param>
/// <param name="xsdFile">xsd文件</param>
/// <param name="namespaceUrl">命名空間,無則默認為null</param>
/// <returns></returns>
public static string XmlValidationByXsd(string xmlFile, string xsdFile, string namespaceUrl = null)
{
StringBuilder sb = new StringBuilder();
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(namespaceUrl, xsdFile);
settings.ValidationEventHandler += (x,y)=>
{
sb.AppendFormat("{0}|", y.Message);
};
using (XmlReader reader = XmlReader.Create(xmlFile, settings))
{
try
{
while (reader.Read());
}
catch (XmlException ex)
{
sb.AppendFormat("{0}|", ex.Message);
}
}
return sb.ToString();
}
