1. 程式人生 > >XML名稱空間詳解

XML名稱空間詳解

一、名稱空間的意義

XML是一種非常好用的標記語言,它具有極好的可擴充套件性,因此當我們需要同時訪問多份XML文件時,有可能會出現這樣一種情況:在同一份XML文件中可能出現多個同名的標籤和屬性,而這些標籤和屬性意義又是完全不同的,這樣如果我們如果不從語法上提供區別,則XML處理器將無法區分它們。

 

為了解決這個問題XML提供了名稱空間的支援。我們想象這樣一個場景,在學校的操場上你喊一句“小明”可能一下子會有好幾個小明迴應你。那你如果喊3年級2班的小明,那可能只會有你找的那個小明迴應你。這裡我們指定了一個範圍(3年級2班),在這個範圍內小明是唯一的。說簡單一些,要確定一個人僅有名字是不夠的,還必須要有一個確定的範圍,這個範圍就可以理解為名稱空間。

 

回到xml中,加入有這樣一個文件,文件中需要儲存圖書的資訊,同時有包含作者的詳細資訊,可以能會是如下一個文件:

<book>

    <title>西遊記</title>

    <author>

       <name>吳承恩</name>

       <title>先生</

title>

    </author>

</book>

這個文件中book有兩個子標籤title和author,title表示書名,author表示作者的資訊。而author中也有一個title屬性,這裡title只的是頭銜稱呼,也就是表示的是稱吳承恩為先生,但是這裡book中的title和author中的title確是兩個完全不同的意思,僅僅靠程式是不能區分開這兩個title的區別的。

 

二、使用字首

 

解決這個問題最好的方法就是為不同的元素起不同的名字。比如:這裡我們可以定一個規則,每一個book下的元素使用一個字首,而author下的使用另一個字首,這樣我們可以通過不同的字首來區分不同的標籤,如此一來我們的文件會變成這個樣子:

<b:book>

    <b:title>西遊記</b:title>

    <a:author>

       <a:name>吳承恩</a:name>

       <a:title>先生</a:title>

    </a:author>

</b:book>

這種方式看起來比較難看,但是確實可以達到區分的目的,現在b:title和a:title就是兩個不同的標籤。

 

通過字首名我們可以很方便的將文件中的標籤分成兩類a和b,帶有字首a的屬於a型別,帶有字首b的屬於b型別,這個類就是名稱空間,這裡你看起來是不是和Java中的包名有著異曲同工的效果呢?

 

但是這裡還存在一個小問題,這裡的名稱空間還只是通過名字來區分不同的標籤,也就是說名稱空間只是為名字進行了一個分類但是名字具體代表了什麼意義,它們應該在哪裡出現,它並沒有一個說明和約束。

 

三、為什麼XML沒有直接使用字首

 

我們上邊這個方法可以解決我們所面臨的問題,但是XML為什麼沒有直接採用這種方式呢?因為這種方式存在一個漏洞,我們通過字首來約束標籤名,那麼字首是否有可能重複呢?加入一份有atguigu定義的xml文件,字首我們設定為a。這裡又一份alibaba定義的文件字首同樣為a,那這兩份文件是不是就會出現重複的標籤呢?所以我們的問題並沒有根本解決。

 

解決這個問題現在變成了我們需要使用一個唯一的字首來確保文件中標籤的唯一性,那麼現實中有哪些東西是唯一的呢?想一下,java中包名採用的是哪種方式?沒錯!就是uri地址,java中通過將uri地址倒著寫來到達區分包的目的,之所以可行就是因為每個公司的uri地址都是唯一的,所以不會出現重複。

 

這裡我們就可以為我們的標籤名使用uri地址作為字首比如 (http://www.atguigu.com/a)title,採用這種方式很顯然出現重複的機率就小多了,但是注意這裡的http://www.atguigu.com/a並不是一個真實的地址,它的目的就是一個確保唯一。

 

這種方式雖然看著可行但是實際上是不現實的,不討論xml中可不可以直接在標籤中編寫uri地址,僅從編寫的角度上看我們也不會這個幹,這玩意太麻煩了!!!

四、XML中如何使用名稱空間

 

XML名稱空間為我們提供了一個標準的語法,宣告XML名稱空間,併為XML文件裡的某個元素或熟悉確定名稱空間。

 

要在文件裡使用XML名稱空間,元素名就變成了限定名(qualified names 縮寫為qName),限定名分成了兩部分,一部分就是我們之前使用的元素名;另一部分是名稱空間的字首,它確定了這個名稱所在的名稱空間。

<b:book xmlns:b="http://www.atguigu.com/xml/b">

 

我們在根標籤中添加了一個xmlns:b屬性,xmlns代表的是xml namespace,b是我們宣告的名稱空間,但是b本身並沒有意義,可以將它理解為是http://www.atguigu.com/xml/b的一個別名,我們在標籤中使用b,就相當於使用這個uri地址。一旦使用了b這個字首,就代表這個標籤是屬於http://www.atguigu.com/xml/b這個名稱空間下的元素。

 

我們還可以在一個文件中定義多個名稱空間,如下的語法也是沒有問題的:

<b:book xmlns:b="http://www.atguigu.com/xml/b" xmlns:a="http://www.atguigu.com/xml/a">

 

五、預設的名稱空間

 

這樣我們在文件中就可以使用a和b兩個字首來區分不同的名稱空間中的標籤了。但是實際上咱們所使用的字首並不友好,為了方便識別在開發中儘量使用便於識別的字首,比如book,author等。

 

採用以上的方式宣告名稱空間已經可以很好的解決了咱們的問題,但是這種方式顯得有一些麻煩,因為每一個標籤都需要加上一個字首,不如直接寫標籤名來的爽快。所以xml還給我們提供了一種方式可以宣告一個預設的名稱空間,具體如下:

<book xmlns="http://www.atguigu.com/xml/b" xmlns:a="http://www.atguigu.com/xml/a">

 

上邊的xmlns="http://www.atguigu.com/xml/b"並沒有指定字首,那麼這種沒有指定字首的名稱空間就會作為頁面中元素的預設名稱空間,除非在標籤中使用其他名稱空間的字首,否則解析器都會認為元素是在預設名稱空間下存在。

但是要注意的是一個文件中只能有一個預設的名稱空間,如下的語法是錯誤的:

<book xmlns="http://www.atguigu.com/xml/b"

xmlns="http://www.atguigu.com/xml/a">

 

這裡我們指定了兩個名稱空間而都沒有使用字首,解析器在解析文件時會不知道使用哪個名稱空間,所以在一個文件中只能有一個預設的名稱空間,其他名稱空間必須使用字首。

 

 

 


本教程由尚矽谷教育大資料研究院出品,如需轉載請註明來源。