16.XML語法、CDATA、約束(DTD、Schema)講解
xml主要用來描述資料,比如配置檔案,網路之間傳輸資料等,並且在android中也經常用xml來佈局,,接下來便來學習xml常用的東西
1.XML語法
xml語法分為:
1.1 文件宣告
- 必須位於文件第一行,用來聲明當前版本、編碼格式以及standlane,如果沒有編碼格式,折則預設為utf-8,比如為<?xml version="1.0" encoding="UTF-8"?>
1.2 元素
- 元素可以包含子元素,文字內容,或者元素屬性.
- 元素名稱不能以數字、標點或者xml(包括任意大小寫)開頭,並且不能包含空格和冒號
比如包含demo文字內容的title元素 :<title>demo</title>
不包含文字的元素:<title></title>
1.3 元素屬性
- 一個元素可以有多個屬性,每個屬性都有它自己的名稱name和取值value.
- 屬性值value必須是引號引起來的,並且屬性名name不能重複
比如:<person name="張三">
1.4 註釋
- 在xml宣告之前不能有註釋
- 註釋語法為:<!—這是註釋-->
- 註釋不能有巢狀,比如這樣使用巢狀是出錯的: <!—這是註釋<!--在嵌套個註釋-->-->
- 在eclipse裡可以通過ctrl+shift+/快捷鍵來快速打出註釋
1.5 CDATA區
- 位於CDATA 區段中的文字會被解析器忽略,不會去解析
- CDATA內容不能包含字串 "]]>"。也不允許巢狀的 CDATA 部分。
- 標記 CDATA內容結尾的 "]]>" 不能包含空格或換行。
- CDATA語法為:<![CDATA[ 內容 ]]>
因為在XML元素中, 字元都會被解析器解析出來,像<>&" 這樣的字元會被直接報錯,示例如下圖所示:
所以如果使用元素無法滿足資料資訊時,則可以通過CDATA來實現,CDATA一般用來儲存函式方法,CSS.大量文字等,比如:
<![CDATA[ body { background: rgb(11,253,216); } ]]>
1.6 轉義字元
由於在XML元素中, 使用<>&" 這樣的字元會被直接報錯,除了通過CDATA區替代外,我們還可以通過轉義字元來實現.
若要在元素中強制使用,需要轉義的字元(包括;)有:
- & : "& ",quotation mark的縮寫
- < : "< ",less-than的縮寫
- > : "> ", greater than的縮寫
- " : "" ", quote的縮寫
- ' : "' ",apostrophe的縮寫
示例如下:
2.XML約束
如果xml格式出現出錯,則程式將不能正確獲取檔案內容,為了保證資料的規範性和安全性,所以可以編寫一個約束文件來約束xml的書寫規範,約束文件可以規範xml中出現的指定元素名稱,屬性以及出現的順序.
常用的約束有兩種:
- DTD約束 :語法簡潔,共能比較單一,如果是外部引用,則編碼格式只能為utf-8編碼,字尾名為.dtd
- Schema約束:語法複雜,功能比較強大,字尾名為.xsd,他是新的xml文件約束,替代DTD的
3.DTD約束
DTD 可被聲明於 XML 文件中,也可作為一個外部引用。
3.1 聲明於 XML 文件
如果內部使用,則可以直接在文件宣告下面寫.格式為"<!DOCTYPE 根元素名稱 [ 約束內容 ]>"
示例如下:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE persons [ <!ELEMENT persons (person+)> <!ELEMENT person (年齡,性別,其它資訊)> <!ELEMENT 年齡 (#PCDATA)> <!ELEMENT 性別 (#PCDATA)> <!ELEMENT 其它資訊 (#PCDATA)> <!ATTLIST person 姓名 ID #REQUIRED 國籍 (中國|外國) #IMPLIED 特點 CDATA "吃睡學習" 動物級別 CDATA #FIXED "高階動物" > <!ENTITY zhangsanMsgUrl "person/id43645.com"> ]> <persons> <person 姓名="zhangsan" 國籍="中國" > <年齡>21</年齡> <性別>男</性別> <其它資訊>zhangsanMsgUrl </其它資訊> </person> <person 姓名="lisi" 特點="吃喝玩樂" > <年齡>21</年齡> <性別>男</性別> <其它資訊> person/id9945.com </其它資訊> </person> </persons>
上面的示例,出現了!ELEMENT、!ATTLIST、#REQUIRED等等DTD約束的關鍵字,接下來我們便來看看這些關鍵字的作用
!ELEMENT-元素定義
ELEMENT關鍵字用來宣告一個XML元素,語法:<!ELEMENT 元素名稱 (使用規則)>
使用規則說明:
- 以逗號,分開 : 表示該元素裡的子元素必須按照順序來寫,所以上面示例的person內的子元素順序為:年齡,性別,其它資訊,如果沒有逗號則表示該元素只能包含指定的子 元素,比如"<!ELEMENT person (年齡)>"表示person元素裡只能有"年齡"子元素
- #PCDATA : 表示元素內容只能是文字,所以上面示例的年齡元素內只能是文字,不能包含子元素.
- + : 表示子元素至少出現一次,所以上面persons裡的person可以有多個.
- ? : 表示子元素出現0次或1次
- * : 表示子元素可有可無
- EMPTY: 表示元素的主體為空
- ANY: 表示元素的內容為任意型別
- 以|分開 : 表示子元素任選其一
!ATTLIST-屬性定義
ATTLIST關鍵字用來約束某個元素的屬性資訊語法:
<!ATTLIST 元素名稱 屬性名 屬性值型別 約束 屬性名 屬性值型別 約束 ...... >
屬性值型別說明
- ID: 表示屬性的取值不能重複(不能與其它相同屬性的值一致),不能只寫數字
- 以|分開 : 表示屬性值任選其一,如果約束為#IMPLIED時,則可以忽略不用選
- CDATA:表示屬性值為文字字串。
約束說明
- #REQUIRED: 表示該屬性必須出現
- #IMPLIED: 表示該屬性可有可無。
- "字串": 表示屬性的取值為預設值。
- #FIXED "字串": 表示該屬性的取值為一個固定字串值
3.2 DTD作為外部引用
如果在xml中要使用外部檔案的DTD約束,則需要在宣告下面寫入宣告的根元素名以及DTD檔名,格式為"<!DOCTYPE 根元素名稱 SYSTEM "檔名稱.dtd">"
示例,將3.1的內部使用改為外部引用 persons.xml檔案如下:
<?xml version="1.0" encoding="utf-8"?> "<!DOCTYPE persons SYSTEM "persons.dtd">" <persons> <person 姓名="zhangsan" 國籍="中國" > <年齡>21</年齡> <性別>男</性別> <其它資訊>zhangsanMsgUrl </其它資訊> </person> <person 姓名="lisi" 特點="吃喝玩樂" > <年齡>21</年齡> <性別>男</性別> <其它資訊> person/id9945.com </其它資訊> </person> </persons>
persons.dtd檔案如下:
<!ELEMENT persons (person+)> <!ELEMENT person (年齡,性別,其它資訊)> <!ELEMENT 年齡 (#PCDATA)> <!ELEMENT 性別 (#PCDATA)> <!ELEMENT 其它資訊 (#PCDATA)> <!ATTLIST person 姓名 ID #REQUIRED 國籍 (中國|外國) #IMPLIED 特點 CDATA "吃睡學習" 動物級別 CDATA #FIXED "高階動物" > <!ENTITY zhangsanMsgUrl "person/id43645.com">
4.Schema約束
- XML Schema是基於 XML 的 DTD 替代者
- XML Schema 符合XML語法結構,並且是可擴充套件的,字尾名為.xsd(xml schema document)
- XML Schema更容易地描述允許的文件內容,以及約束定義, 並支援名稱空間.
4.1 示例-建立personSchema.xsd
在eclipse中,點選File->new->other,然後建立XML Schema File檔案,名字為personSchema.xsd.內容如下:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.org/personSchema" targetNamespace="http://www.example.org/personSchema" elementFormDefault="qualified"> <!--講解1--> <xs:element name='persons'> <!--約束xml根元素為persons--> <xs:complexType> <!--complexType:定義persons為複合元素--> <xs:sequence maxOccurs='unbounded '> <!--講解2--> <xs:element name='person'> <!--約束persons下的子元素名字必須為person--> <xs:complexType> <xs:sequence> <!--sequence:必須按照順序實現:先有姓名,最後年齡.--> <xs:element name='姓名' type='xs:string' /> <xs:element name='性別' type='xs:string' /> <xs:element name='年齡' type='xs:string' /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
講解1:
xmlns:xs=http://www.w3.org/2001/XMLSchema
- 約束XML裡使用xs:作字首的元素、屬性、型別等名稱的變數是屬於http://www.w3.org/2001/XMLSchema名稱空間的。
xmlns=http://www.example.org/personSchema
- 表示預設的名稱空間是http://www.example.org/personSchema,也就是指定未使用任何字首的元素、資料的名稱空間為它.
targetNamespace="http://www.example.org/personSchema"
- 顯示被此 schema 定義的元素來自名稱空間: http://www.example.org/personSchema
講解2:
<xs:sequence maxOccurs='unbounded'>
- sequence表示必須按照順序實現, maxOccurs='unbounded'表示可以有多個相同的,比如上面就是表示persons裡可以有多個person.
4.2 示例-建立對應的XML
然後在eclips中點選 File->new->other,然後建立XML檔案,名字為person.xml,然後點選next,然後選擇建立基於schema的XML:
再選擇我們剛剛寫好的personSchema.xsd:
然後設定檔名為person.xml,且內容如下:
<?xml version="1.0" encoding="UTF-8"?> <p:persons xmlns:p="http://www.example.org/personSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/personSchema personSchema.xsd "> <p:person> <p:姓名>p:張三</p:姓名> <p:性別>p:男</p:性別> <p:年齡>p:22</p:年齡> </p:person> <p:person> <p:姓名>p:李四</p:姓名> <p:性別>p:男</p:性別> <p:年齡>p:17</p:年齡> </p:person> </p:persons>
xmlns:p="http://www.example.org/personSchema"
- 表明此schema中使用的字首為p:的元素和資料型別來自於"http://www.example.org/personSchema"名稱空間
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- 指定定義的XML例項名稱空間規範格式.預設都以這個2001版本為使用
xsi:schemaLocation="http://www.example.org/personSchema personSchema.xsd ">
- 指定我們使用的"http://www.w3.org/2001/XMLSchema"名稱空間的約束格式為personSchema.xsd約束檔案的內容(也就是說該xml被personSchema.xsd所約束)
4.3 驗證
如下圖所示,假如我們不按照personSchema.xsd約束來寫XML,則直接出現error:
未完待續,下章學習java解