1 xml 約束的概念
- XML 指可擴展標記語言(EXtensible Markup Language)
- XML 是一種標記語言,很類似 HTML
- XML 的設計宗旨是傳輸數據,而非顯示數據
- XML 標簽沒有被預定義。您需要自行定義標簽。
- XML 被設計為具有自我描述性質。
因為xml文件是可擴展的,且里面的標簽可以自定義的,只要符合xml的最基本要求,那么就可以寫一個xml文件。但是在實際應用中,我們需要針對某一個特定的應用,給xml中引入一下語法,這些語法用來檢測特定應用的xml文件編寫是否正確。例如mybatis中使用的DTD約束,spring中使用的shema約束。
xml約束就是在特定應用下,為xml編寫的一下語法,用來檢測這個應用下的xml文件是否正確。
2 xml約束常用的兩種約束
(1) DTD約束
描述約束的文件是以.dtd為擴展名,dtd約束作用於xml文檔,會有兩種方式
(一)把dtd約束直接寫到xml文檔中
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE users[ <!ELEMENT users (user+) > <!ELEMENT user (name,age,addr) > <!ELEMENT name (#PCDATA) > <!ELEMENT age (#PCDATA) > <!ELEMENT addr (#PCDATA) > ]> <users> <user> <name>zhangsan</name> <age>23</age> <addr>shanghai</addr> </user> <user> <name>lisi</name> <age>24</age> <addr>beijing</addr> </user> </users>
(二)在xml文檔中引用一個外部的dtd約束文檔(dtd約束文檔以.dtd作用擴展名),
外部引用又包括兩種,
一種是SYSTEM 系統外部約束文檔,也就是xml文檔和dtd約束文檔都在同一台機器上,
一種是PUBLIC公共外部約束文檔,也就是xml文檔和dtd約束文檔不在同一台機器上,需要通過網絡把dtd文檔下載到本地
引用形式如下
<!DOCTYPE 根元素 SYSTEM "dtd文件路徑"> <!DOCTYPE 根元素 PUBLIC "dtd文件的描述信息" "dtd的url">
SYSTEM 系統外部約束文檔示例
PUBLIC公共外部約束文檔 示例
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
DOCTYPE后面的mapper就是整個xml的根標簽, PUBLIC表示引用的dtd約束是一個公共約束
(2)shema約束
shema約束簡介
Schema它也來約束xml文件的,DTD在約束xml的時候一個xml中只能引入一個DTD,同時DTD它無法對屬性以及標簽中的數據做數據類型的限定。
Schema它是用來代替DTD來約束xml。
Schema文件本身就是使用xml文件書寫的,同時它對需要約束的xml中的數據有嚴格的限定。
學習Schema主要來學習W3C組織定義的如何在Schema中去約束xml的標簽以及屬性,還有屬性的數據類型,以及標簽中子標簽的順序。
要定義一個Schema文件,這時它的擴展名必須是.xsd。在這個文件中根元素必須是schema。
使用Schema來約束xml,Schema在書寫的時候,只需要使用W3C組織提前定義的限定標簽的,以及限定的屬性的那個標簽即可。
shema約束定義案例
在定義Schema文件的時候,由於這個Schema文件本身就是xml,它也要受到別的約束。而這個約束是W3C組織提前定義好的, 在Schema文件中需要提前引入進來在根標簽中使用屬性進行進入: <schema xmlns="http://www.w3.org/2001/XMLSchema" 引入W3C定義的schema書寫的約束 targetNamespace="http://www.itcast.org/book" 給當前的Schema文件起名字(命名空間) 作用是當哪個xml要引入這個schema約束的時候,必須通過當前targetNamespace 后面書寫的uri地址來引入
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.itcast.org/book" elementFormDefault="qualified"> <element name="books"> <complexType> <sequence> <element name="book"> <complexType> <sequence> <element name="name"></element> <element name="author"></element> <element name="price"></element> </sequence> </complexType> </element> </sequence> </complexType> </element> </schema>
在xml文件中引入當前的這個Schema
schema instance(schema 實例),這個概念類似於類實例(對象),http://www.w3.org/2001/XMLSchema 這個定義schema約束文件的元約束文件的命名空間,通過這個元約束的命名空間定義的schema約束文件就是schema實例。也就是說schema實例其實就是schema約束文件,就像類實例就是類對象一樣。
<books xmlns="http://www.itcast.org/book" 它是schema文件中的targetNamespace 屬性的值 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 說明當前的xml是schema一個實例文檔,其真正的含義是xml schema instances 命名空間,也就是所有的shema實例都在這里面,是和下面的 sxi:shemaLocation進行綁定的 xsi:schemaLocation="http://www.itcast.org/book book.xsd" 這個是在引入當前的schema文件的真實路徑 >
在每個xml文件中,我們都會看到 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 這個命名空間是實例命名空間,我們在xml中引入的schema實例,都必須和 "http://www.w3.org/2001/XMLSchema-instance" 進行綁定,綁定是通過一個前綴進行綁定。在books.xml中,這個前綴是xsi 。
上圖未沒有進行綁定,報錯信息如下:
The prefix "test" for attribute "test:schemaLocation" associated with an element type "books" is not bound.
books元素的"test:schemaLocation"屬性的前綴沒有綁定
其實schema實例命名空間的前綴可以修改,例如把前綴修改成test,那么上圖就不會報錯,示例如下圖
描述約束的文件以 .xsd為擴展名,在xml中引入多個shema的約束如下
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> </beans>
在引入shema約束時,並沒有再另外使用新的標簽(DTD約束使用<!DOCTYPE>標簽引入約束),而是在根標簽中使用xmlns屬性來引入約束,xmlns是xml namespace的簡寫。並通過 xsi:schemaLocation="" 把schema約束的位置進行指定,一般情況下會按照指定的位置到網絡中下載約束文件,如果沒有網絡,需要自己指定本地約束文件。