1. 程式人生 > >XML和Schema中xmlns,targetNamespace和xsi:schemaLocation的關係和作用

XML和Schema中xmlns,targetNamespace和xsi:schemaLocation的關係和作用

XML的名稱空間:

在w3c的官方說法中,名稱空間提供了避免元素命名衝突的作用,即相同的元素名稱表示不同含義的情況。
這裡就不再舉例詳細說明了,在網上很容易找到。如果要避免重名的衝突,那很明顯的,在xml文件中就可以出現多個不同的名稱空間。
名稱空間的語法:
xmlns:namespace-prefix="namespaceURI"
當名稱空間被定義在元素的開始標籤中時,所有帶有相同字首的子元素都會與同一個名稱空間相關聯,字首可以看做是名稱空間的一個別名;

xmlns:是預設名稱空間。如果不加字首(namespace-prefix),即為預設名稱空間,指定使用該名稱空間的元素及子元素只要不加其他字首,就都是預設名稱空間的元素。

XML Schema:

XML Schema是定義 XML文件的合法構建模組,即定義xml文件中可以出現哪些元素、屬性、元素之間的關係、順序、元素的數量、元素或屬性的型別和值的範圍等等,是對xml文件的一種約束方式。

不過xsd(XML Schema Definition,即XML Schema定義)文件本身也是使用XML語言來寫的。所以它也具有xmlns的屬性。

下面給出一個簡單的xsd文件:

book.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
		targetNamespace="http://www.example.org/book"
		xmlns="http://www.example.org/book" 
		elementFormDefault="qualified">
	
	<xs:element name="books" type="booksType"/>
	<xs:complexType name="booksType">
		<xs:sequence>
			<xs:element name="book" type="bookType" maxOccurs="unbounded"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="bookType">
		<xs:sequence>
			<xs:element name="name" type="xs:string"/>
			<xs:element name="author" type="xs:string"/>
			<xs:element name="price" type="priceType"/>
		</xs:sequence>
		<xs:attribute name="id" type="xs:string" use="required"/>
	</xs:complexType>
	<xs:simpleType name="priceType">
		<xs:restriction base="xs:decimal">
			<xs:minExclusive value="0"/>
			<xs:maxInclusive value="500"/>
		</xs:restriction>
	</xs:simpleType>
	
</xs:schema>
targetNamespace:

該屬性聲明瞭本XML Schema文件中定義的元素是屬於targetNamespace屬性指定的名稱空間(URI)下的。

有一個現象,在很多xsd文件中會發現,xmlns和targetNamespace指定的名稱空間值(URI)是一樣的,但其實他們之間的關係並不是固定的。為什麼這樣說呢?

因為targetNamespace聲明瞭在該xsd文件下定義的元素屬於該名稱空間,而xmlns的作用僅僅是指定預設名稱空間

但是,如果在eclipse或idea等IDE工具裡,一個xmlns和targetNamespace的URI相同的xsd文件(比如上面給出的book.xsd),將xmlns或targetNamespace修改的不一致,會發現IDE在該xsd文件引用自定義的元素時會報錯,如下圖,是將上面的文件的targetNamespace修改為“http://www.example.org/book_modify”。


這麼一看它們之間看起來好像又有關聯?

其實是因為當預設名稱空間xmlns和targetNamespace指定的名稱空間一致時,在預設名稱空間下使用的元素(如:type="booksType")是屬於targetNamespace名稱空間下的。所以在這種情況下,當只是修改xmlns或者targetNamespace,使兩者不一致時,IDE工具會發現在xmlns引用的名稱空間下找不到該元素的定義的錯誤。

當然,也可以將預設名稱空間xmlns和targetNamespace給定不一樣的值,用另外加了字首的名稱空間引用targetNamespace的名稱空間下的元素,這樣在使用targetNamespace下定義的元素時需要加上該字首。如下:

book_modify.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
		xmlns="http://www.example.org/other" 
		targetNamespace="http://www.example.org/book"
		xmlns:bo="http://www.example.org/book"
		elementFormDefault="qualified">
	<!-- 
		將xmlns定義為其他值。
		增加新的名稱空間xmlns:bo="http://www.example.org/book",其值是targetNamespace的URI。
		這樣,要是使用在targetNamespace下定義的元素,需要使用字首bo。
	-->
	<xs:element name="books" type="bo:booksType"/><!-- 使用了bo字首 -->
	<xs:complexType name="booksType">
		<xs:sequence>
			<xs:element name="book" type="bo:bookType" maxOccurs="unbounded"/><!-- 使用了bo字首 -->
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="bookType">
		<xs:sequence>
			<xs:element name="name" type="xs:string"/>
			<xs:element name="author" type="xs:string"/>
			<xs:element name="price" type="bo:priceType"/><!-- 使用了bo字首 -->
		</xs:sequence>
		<xs:attribute name="id" type="xs:string" use="required"/>
	</xs:complexType>
	<xs:simpleType name="priceType">
		<xs:restriction base="xs:decimal">
			<xs:minExclusive value="0"/>
			<xs:maxInclusive value="500"/>
		</xs:restriction>
	</xs:simpleType>
	
</xs:schema>
XML中使用Schema例項:

這裡先給出一個使用book.xsd來約束的xml檔案

books.xml

<?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文件中,經常看到 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"這樣的名稱空間,那它有什麼作用呢?

它的作用是告知xml文件解析器,用某個schema例項來驗證該xml文件。而且該名稱空間的URI

http://www.w3.org/2001/XMLSchema-instance”是一個固定值,這個URI指向一個xsd文件,該xsd的targetNamespace的值就是這個URI。同時在xsd中定義了四個屬性,其中有一個屬性的名稱為:schemaLocation,這個屬性在xml文件中也經常用到,如上面的例子中

xsi:schemaLocation="http://www.example.org/book book.xsd"
xsi:schemaLocation的作用:

其語法是:schemaLocation=“{namespaceURI}   {xsd名稱}”

字首xsi是自定義的,不過現在大家都習慣了這個官方的習慣。

其作用是告知解析器,schemaLocation指定的名稱空間下的元素要用該xsd的schema來約束。就像該屬性的名稱的字面意義,確定schema的定位。

但是,如果要讓該schema起到作用,需要在xml中使xmlns的URI和該xsd文件的targetNamespace的URI相同。且在schemaLocation中,namespaceURI的值一定要和該xmlns相同,也就是和xsd檔案的targetNamespace相同,這樣,解析器才能準確的知道在該xmlns下的元素要遵循哪個schema。當然也可以在xmlns後加名稱空間的字首,在該字首修飾的元素需要遵循該schema的規範。例如:

books_modify.xml

<?xml version="1.0" encoding="UTF-8"?>
<m:books xmlns:m="http://www.example.org/book"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.example.org/book book.xsd">
	<m:book id="1001">
		<m:name>Thinking in Java</m:name>
		<m:author>Bruce Eckel</m:author>
		<m:price>86.4</m:price>
	</m:book>
	<m:book id="1002">
		<m:name>Head First 設計模式</m:name>
		<m:author>Freeman</m:author>
		<m:price>64.2</m:price>
	</m:book>
	<m:book id="1003">
		<m:name>深入理解Java虛擬機器</m:name>
		<m:author>周志明 </m:author>
		<m:price>59.2</m:price>
	</m:book>
</m:books>

參考連結: