1. 程式人生 > >關於XML和Schema約束的一些總結。

關於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