天天看點

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間

Java語言使用包來避免名字沖突。程式員可以為不同的類使用相同的名字,隻要它們不在同一個包中即可。XML也有類似的命名空間(namespace)機制,可以用于元素名和屬性名。

名字空間是由統一資源辨別符(Uniform Resource Identif?ier, URI)來辨別的,比如:

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間

HTTP的URL格式是最常見的辨別符。注意,URL隻用作辨別符字元串,而不是一個檔案的定位符。例如,名字空間辨別符:

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間

表示了不同的命名空間,盡管Web伺服器将為這兩個URL提供同一個文檔。

為什麼要用HTTP URL作為命名空間的辨別符?這是因為這樣容易確定它們是獨一無二的。如果使用實際的URL,那麼主機部分的唯一性就将由域名系統來保證。然後,你的組織可以安排URL餘下部分的唯一性,這和Java包名中的反向域名是一個原理。

盡管長名字空間的唯一性很好,但是你肯定不想處理超出必需範圍的長辨別符。在Java程式設計語言中,可以用import機制來指定很長的包名,然後就可以隻使用較短的類名了。在XML中有類似的機制,比如:

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間

現在,該元素和它的子元素都是給定命名空間的一部分了。

子元素可以提供自己的命名空間,例如:

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間

這時,第一個子元素和孫元素都是第二個命名空間的一部分。

無論是隻需要一個命名空間,還是命名空間本質上是嵌套的,這個簡單機制都工作得很好。如若不然,就需要使用第二種機制,而Java中并沒有類似的機制。你可以用一個字首來表示命名空間,即為特定文檔選取的一個短的辨別符。下面是一個典型的例子:

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間
《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間
《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間

  

你可以控制解析器對命名空間的處理。預設情況下,Java XML庫的DOM解析器并非“命名空間感覺的”。

要打開命名空間處理特性,請調用DocumentBuilderFactory類的setNamespace Aware方法:

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間

這樣,該工廠産生的所有生成器便都支援命名空間了。每個節點有三個屬性:

帶有字首的限定名(qualif?ied),由getNodeName和getTagName等方法傳回。

命名空間URI,由getNamespaceURI方法傳回。

不帶字首和命名空間的本地名(local name),由getLocalName方法傳回。

下面是一個例子。假設解析器看到了以下元素:

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間

它會報告如下資訊:

限定名 = xsd:schema

本地名 = schema

注意:如果對命名空間的感覺特性被關閉,getLocalName和getNamespaceURI方法将傳回null。

《Java核心技術 卷Ⅱ 進階特性(原書第10版)》一3.5 使用命名空間