關於XML和Schema約束的一些總結。
在學習XML約束的時候DTD約束還比較易懂(也可能是錯覺),但是Schema約束的名稱空間、引入,Schemalocation等比較難懂,總結一下最近自己檢視其他專家的部落格琢磨出來的東西
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" //這裡可能有錯誤,該xsd檔案多定義了一行預設的xmlSchema targetNamespace="http://www.example.org/web-app_2_5" xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:tns="http://www.example.org/web-app_2_5" elementFormDefault="qualified"> <xsd:element name="web-app"> <xsd:complexType> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element name="servlet"> <xsd:complexType> <xsd:sequence> <xsd:element name="servlet-name"></xsd:element> <xsd:element name="servlet-class"></xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="servlet-mapping"> <xsd:complexType> <xsd:sequence> <xsd:element name="servlet-name"></xsd:element> <xsd:element name="url-pattern" maxOccurs="unbounded"></xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="welcome-file-list"> <xsd:complexType> <xsd:sequence> <xsd:element name="welcome-file" maxOccurs="unbounded"></xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> <xsd:attribute name="version" type="double" use="optional"></xsd:attribute> </xsd:complexType> </xsd:element> </xsd:schema>
這是一個XSD約束檔案,其中
xmlns與xmlns:nsd、xmlns:tns稱為對名稱空間的引用,xmlns稱為預設名稱空間,xmlns:字首 稱為顯式名稱空間,這兩個有什麼區別?
如果使用的是xmlns中定義的元素、屬性、型別等成員直接使用即可,例如:<servlet>
如果使用的是xmlns:字首中定義的元素、屬性、型別等成員則需要在前面加上字首,例如:<xsd:element>
“http://www.w3.org/2001/XMLSchema”是每個xsd檔案必須有的名稱空間,定義了element, attribute, complexType, group, simpleType等元素。
targetNamespace屬性對本xsd檔案所在的名稱空間進行了定義,就好像java檔案頭上的“package cn.haiyisoft.xml”這個一樣,說明了我這個java文件是在這個包下一樣
xmlns與targetNamespace的關係,targetNamespace是定義了名稱空間,而xmlns是將這個名稱空間進行引入;xsd檔案中定義了一個targetNameSpace後,其內部定義的元素,屬性,型別等都屬於該targetNameSpace,其自身或外部xsd檔案使用這些元素,屬性等都必須從定義的targetNameSpace中找。這就是xsd約束檔案的一個很奇怪的地方,就算我某個成員定義在我檔案內部,你想直接用也不行,必須用xmlns將我這個名稱空間引入,如下例子:
xsd檔案中定義了一個targetNameSpace後,其內部定義的元素,屬性,型別等都屬於該targetNameSpace,其自身或外部xsd檔案使用這些元素,屬性等都必須從定義的targetNameSpace中找。修改一下note.xsd,去除預設名稱空間的宣告,並新增一個複雜型別:
<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" elementFormDefault="qualified"> <xsd:element name="note"> <xsd:complexType> <xsd:sequence> <xsd:element name="to" type="xs:string"/> <xsd:element name="from" type="xs:string"/> <xsd:element name="heading" type="xs:string"/> <xsd:element name="body" type="xs:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Student" type="stu"/> <xsd:complexType name="stu"> <xsd:sequence> <xsd:element name="Name" type="xs:string"/> <xsd:element name="Class" type="xs:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema>
上述程式碼中,複雜型別stu是找不到的,因為你定義了一個名稱空間"http://www.w3schools.com",該複雜型別存在於"http://www.w3schools.com"中,因此應該修改程式碼如下:
<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" xmlns:student="http://www.w3schools.com" elementFormDefault="qualified"> <xsd:element name="note"> <xsd:complexType> <xsd:sequence> <xsd:element name="to" type="xs:string"/> <xsd:element name="from" type="xs:string"/> <xsd:element name="heading" type="xs:string"/> <xsd:element name="body" type="xs:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Student" type="student:stu"/> <xsd:complexType name="stu"> <xsd:sequence> <xsd:element name="Name" type="xs:string"/> <xsd:element name="Class" type="xs:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema>
若自身並不使用重用定義的成員,僅供外部使用的話,則只定義targetNameSpace就可以,不用特別把自己的名稱空間再次引入。
為什麼xsd也有xmlns等屬性呢?因為xsd也是一個xml文件啊,只不過字尾名變成了.xsd
關於elementFormDefault 有qualified和unqualified使用來規定是否只有全域性成分才被定義在目標名稱空間中。
<?xml version="1.0" encoding="UTF-8"?> <books xmlns="http://www.example.org/book" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/book book.xsd"> <book id="1001"> <name>Thinking in Java</name> <author>Bruce Eckel</author> <price>86.4</price> </book> <book id="1002"> <name>Head First 設計模式</name> <author>Freeman</author> <price>64.2</price> </book> <book id="1003"> <name>深入理解Java虛擬機器</name> <author>周志明 </author> <price>59.2</price> </book> </books>
以上是一個xml檔案
其中“http://www.w3.org/2001/XMLSchema-instance”是必須有的,它定義了一些成員,其中schemaLocation就是它其中定義的一個屬性,所以根元素中的schemaLocation需要加xsi字首
schemaLocation是一個類似於鍵值對的形式,由路徑和檔名組成,以給解析器說明約束檔案所在的位置,其中的路徑必須和摸個xmlns引入的名稱空間相同,也與此約束檔案的targetNamespace的值相同
本文的參考來自於
1.https://blog.csdn.net/qq_38724991/article/details/76131614
2.https://blog.csdn.net/wanghuan203/article/details/9203621
3.https://blog.csdn.net/wanghuan203/article/details/9204337
4.https://blog.csdn.net/freelk/article/details/80869439#commentBox
5.https://blog.csdn.net/pzasdq/article/details/52592819
6.https://blog.csdn.net/ruizhe_hao/article/details/53432558
7.https://www.cnblogs.com/TIMHY/p/7780642.html
8.https://www.cnblogs.com/ihanliu/p/4718795.html