XML Namespace 命名空間

根據 Namespaces in XML W3C 推薦標準的定義,XML 命名空間 是由國際化資源標識符 (IRI) 標識的 XML 元素和屬性集合;該集合一般稱做 XML「詞彙」。html

定義 XML 命名空間的主要動機之一是在使用和重用多個詞彙時避免名稱衝突。XML 模式用於爲 XML 實例建立一個詞彙並頻繁使用命名空間。所以,正確理解命名空間概念對於從整體上理解 XML 模式和實例驗證相當重要。瀏覽器

命名空間在多個方面相似於 Java 中的程序包:oracle

  • Java 中的程序包能夠包含許多可重用的類和接口。一樣,XML 中的命名空間能夠有許多可重用的元素和屬性。
  • 要使用程序包中的類或接口,必須使用程序包名稱徹底限定該類或接口。一樣,要使用命名空間中的元素或屬性,必須使用命名空間徹底限定該元素或屬性。
  • Java 程序包可能有一個內部類,該類並不直接位於程序包內部,而是藉助它的外圍類「屬於」該程序包。命名空間也是如此:某些元素或屬性可能並不直接在命名空間中,而是藉助它的父元素或外圍元素而屬於命名空間。這是一個傳遞關係。若是桌子上有一本書,而桌子在地面上,則根據傳遞關係,這本書位於地面上;儘管這本書並不是 直接位於地面上。

 

所以,能夠看出 XML 概念中的命名空間與 Java 中的程序包並沒有多大區別。這種對比旨在簡化對 XML 中命名空間的瞭解,並幫助您直觀認識命名空間的概念。工具

在本文中,您將瞭解:ui

  • 命名空間在 XML 中的做用
  • 如何聲明和使用命名空間
  • 默認命名空間與無命名空間之間的區別
  • 如何使用 XML 模式建立命名空間,以及
  • 命名空間中的限定和非限定元素/屬性之間的區別。

聲明和應用命名空間

命名空間被聲明爲元素的屬性。並不必定只在根元素聲明命名空間;而是能夠在 XML 文檔中的任何元素中進行聲明。聲明的命名空間的範圍起始於聲明該命名空間的元素,並應用於該元素的全部內容,直到被具備相同前綴名稱的其餘命名空間聲明覆蓋—其中,元素內容是指該元素的 <opening-tag> 和 </closing-tag> 之間的內容。命名空間聲明以下:spa

<someElement xmlns:pfx="http://www.foo.com" />3d

在屬性 xmlns:pfx 中,xmlns 相似於一個保留字,它只用於聲明命名空間。換言之, xmlns 用於綁定命名空間,但其自己並不綁定到任何命名空間。所以,以上示例其實是將前綴「pfx」與命名空間「http://www.foo.com」綁定在一塊兒。code

一般將 XSD 或 XS 用做 XML 模式命名空間的前綴,但具體使用什麼前綴徹底取決於我的。您能夠選擇將前綴 ABC 用於 XML 模式命名空間,這是合法的,但沒有什麼意義。使用有意義的命名空間前綴加強了 XML 文檔的清晰性。請注意,前綴只用做佔位符,而且必須經過能夠識別命名空間的 XML 分析器進行解釋才能使用綁定到該前綴的實際命名空間。在 Java 類比中,命名空間綁定能夠比做聲明一個變量,而且每當引用該變量時,它將被所賦與的值替換。orm

在上一個命名空間聲明示例中,每當在命名空間範圍中引用前綴「pfx」時,它將被解釋爲綁定到實際的命名空間 ( http://www.foo.com):xml

在 Java 中: String pfx = "http://www.library.com"

在 XML 中: <someElement xmlns:pfx="http://www.foo.com" />

儘管命名空間一般看上去像 URL,但這並不意味着實際聲明和使用命名空間時必定要鏈接到互聯網上。實際上,一般將命名空間用做能夠在互連網空間中共享詞彙和不顯示內容的虛擬「容器」。在互連網空間中,URL 是惟一的—所以,您一般選擇使用 URL 來惟一標識命名空間。在瀏覽器中鍵入命名空間 URL 並不意味着它將顯示該命名空間中的全部元素和屬性;它只是一個概念。

但這裏存在一種誤解:儘管 Namespaces in XML W3C 推薦標準聲明該命名空間名稱應爲 IRI,但它對此並沒有強制規定。所以,我還可使用如下代碼:

<someElement xmlns:pfx=" foo" />

該代碼徹底合法。

至此應明瞭,要使用命名空間,首先應使用前綴綁定將其綁定,而後在須要時使用該前綴。但爲何不能從一開始便使用命名空間限定元素或屬性呢?首先,因爲命名空間(做爲 IRI)很是長,所以毫無疑問會使 XML 文檔雜亂不堪。第二,也是最重要的,它可能對語法形成嚴重影響,或者具體一點說,可能對 XML 的生產規則形成嚴重影響—緣由是 IRI 可能包含 XML 1.0 W3C 推薦標準 不容許在 XML 標記中使用的字符。

無效) <http://www.library.com:Book />
有效) <lib:Book xmlns:lib="http://www.library.com" />

 下面的元素 Title 和 Author 與命名空間 http://www.library.com 關聯:

<?xml version="1.0"?>
<Book xmlns:lib="http://www.library.com">
    <lib:Title>Sherlock Holmes</lib:Title>
    <lib:Author>Arthur Conan Doyle</lib:Author>
</Book>

在下面的示例中, Sherlock Holmes - III 和 Sherlock Holmes - I 的元素 Title 和 Author 與命名空間http://www.library.com 關聯, Sherlock Holmes - II 的元素 Title 和 Author 與命名空間 http://www.otherlibrary.com關聯。

<?xml version="1.0"?>
<Book xmlns:lib="http://www.library.com">
    <lib:Title>Sherlock Holmes - I</lib:Title>
    <lib:Author>Arthur Conan Doyle</lib:Author>
    <purchase xmlns:lib="http://www.otherlibrary.com">
        <lib:Title>Sherlock Holmes - II</lib:Title>
        <lib:Author>Arthur Conan Doyle</lib:Author>
    </purchase>
    <lib:Title>Sherlock Holmes - III</lib:Title>
    <lib:Author>Arthur Conan Doyle</lib:Author>
</Book>

Namespaces in XML W3C 推薦標準規定了某些命名空間約束:

  1. 以三字母序列 x、m 和 l(採用任何大小寫組合)開頭的前綴被保留,供 XML 和 XML 相關的規範使用。儘管這不是一個嚴重錯誤,但綁定此類前綴並不可取。前綴 xml 根據定義綁定到命名空間名稱 http://www.w3.org/XML/1998/namespace
  2. 只有已聲明並綁定到命名空間的前綴才能使用。(是否曾經試過在 Java 中使用沒有聲明的變量?)

如下代碼違反了這些約束:

<?xml version="1.0"?>
<Book xmlns:XmlLibrary="http://www.library.com">
    <lib:Title>Sherlock Holmes - I</lib:Title>
    <lib:Author>Arthur Conan Doyle</lib:Author>
</Book>

[錯誤]:前綴 lib 未綁定到命名空間。 
[不可取]:前綴 XmlLibrary 以「Xml」開頭。

 

單個默認命名空間(而非多個默認命名空間)

重複限定一個要在命名空間中使用的元素或屬性可能會很是麻煩。這種狀況下,能夠聲明一個 {默認命名空間}。記住,不管在任什麼時候候都只能存在一個 {默認命名空間}。所以,術語「多個默認命名空間」在其實是不正確的。

聲明一個 {默認命名空間} 意味着,若是 {默認命名空間} 聲明範圍內的任何元素未使用前綴顯式限定,則該元素將被隱式限定。與帶前綴的命名空間同樣,{默認命名空間} 也能夠被覆蓋。{默認命名空間} 聲明以下:

<someElement xmlns="http://www.foo.com"/>

 

<?xml version="1.0"?>
<Book xmlns="http://www.library.com">
    <Title>Sherlock Holmes</Title>
    <Author>Arthur Conan Doyle</Author>
</Book>

這種狀況下,元素 Book、Title 和 Author 與命名空間 http://www.library.com 關聯。

記住,命名空間的範圍起始於聲明該命名空間的元素。所以,元素 Book 還與 {默認命名空間}關聯,這是由於它沒有前綴。

<?xml version="1.0"?>
<Book xmlns="http://www.library.com">
    <Title>Sherlock Holmes - I</Title>
    <Author>Arthur Conan Doyle</Author>
    <purchase xmlns="http://www.otherlibrary.com">
        <Title>Sherlock Holmes - II</Title>
        <Author>Arthur Conan Doyle</Author>
    </purchase>
    <Title>Sherlock Holmes - III</Title>
    <Author>Arthur Conan Doyle</Author>
</Book>

在以上的示例中, Sherlock Holmes - III 和 Sherlock Holmes - I 的元素 Book、 Title 和 Author 與命名空間http://www.library.com 關聯, Sherlock Holmes - II 的元素 purchase、 Title 和 Author 與命名空間http://www.otherlibrary.com 關聯。

默認命名空間和屬性

默認命名空間不該用於屬性;所以,要將命名空間應用於屬性,必須顯式限定該屬性。此處的屬性 isbn {沒有命名空間},而屬性 cover 與命名空間 http://www.library.com 關聯。

<?xml version="1.0"?>
<Book isbn="1234"
      pfx:cover="hard"
      xmlns="http://www.library.com"
      xmlns:pfx="http://www.library.com">
    <Title>Sherlock Holmes</Title>
    <Author>Arthur Conan Doyle</Author>
</Book>

取消聲明命名空間

Namespaces in XML 1.0 W3C 推薦標準不容許取消綁定已經綁定的前綴,而 Namespaces in XML 1.1 W3C 推薦標準則容許這樣作。1.0 沒有理由不容許取消綁定,不過該錯誤已經在 1.1 中獲得修正。沒必要知道此差異,這是由於支持 Namespaces in XML 1.1 的 XML 分析器並很少。

儘管取消綁定帶前綴的命名空間有一些差異,但這兩個版本均容許您取消綁定或刪除已聲明的 {默認命名空間}:用其餘 {默認命名空間} 聲明(覆蓋聲明中的命名空間爲空)覆蓋已聲明的 {默認命名空間}。取消綁定命名空間與未聲明命名空間具備一樣的效果。此處的 Sherlock Holmes - III 和 Sherlock Holmes - I 的元素 Book、Title 和 Author 與命名空間 http://www.library.com 關聯,而Sherlock Holmes - II 的元素 purchase、 Title 和 Author {沒有命名空間}:

<someElement xmlns="" />
<?xml version="1.0"?>
<Book xmlns="http://www.library.com">
    <Title>Sherlock Holmes - I</Title>
    <Author>Arthur Conan Doyle</Author>
    <purchase xmlns="">
        <Title>Sherlock Holmes - II</Title>
        <Author>Arthur Conan Doyle</Author>
    </purchase>
    <Title>Sherlock Holmes - III</Title>
    <Author>Arthur Conan Doyle</Author>
</Book>

此處是根據 XML 1.0 規範中的命名空間取消綁定前綴的無效示例,而根據 XML 1.1 中的命名空間取消綁定前綴則是有效的:

<purchase xmlns:lib="">

今後處開始,前綴 lib 不能在 XML 文檔中使用,由於只要您在元素 purchase 的範圍內,它就保持未聲名狀態。固然,您徹底能夠再次定義它。

 

無名稱空間

若是範圍中沒有默認命名空間,便不存在命名空間。{默認命名空間} 是使用 xmlns 顯式聲明的命名空間。若是未使用 xmlns 聲明 {默認命名空間},則不能說元素位於 {默認命名空間} 中。這種狀況下,咱們能夠說元素位於 {無命名空間} 中。當已聲明的 {默認命名空間} 被取消聲明時,也將應用 {無命名空間}。

摘要:

  • 聲明的命名空間的範圍起始於聲明該命名空間的元素,並應用於該元素的全部內容,直到被具備相同前綴名稱的其餘命名空間聲明覆蓋
  • 帶前綴的命名空間和 {默認命名空間} 均可以被覆蓋。
  • 帶前綴的命名空間和 {默認命名空間} 均可以被取消聲明。
  • {默認命名空間} 不直接應用於屬性。
  • 僅當顯式聲明 {默認命名空間} 時,該命名空間才存在。若是未聲明默認命名空間,則不該使用術語 {默認命名空間}。
  • 若是範圍中沒有默認命名空間,便不存在命名空間。

 

命名空間和 XML 模式

到目前爲止,咱們已經瞭解瞭如何聲明和使用現有命名空間。如今,讓咱們瞭解如何建立一個新命名空間,並使用 XML 模式將元素和屬性添加到其中。

XML 模式首先是一個 XML。換言之,同任何其餘 XML 文檔同樣,XML 模式使用元素和屬性構建。此「構建材料」必須出自命名空間http://www.w3.org/2001/XMLSchema,它是已聲明和保留的命名空間,其中包含 W3C XML 模式結構規範 和 W3C XML 模式數據類型規範 中定義的元素和屬性。不該將元素或屬性添加到該命名空間。

使用這些構建塊,能夠根據須要建立新元素和屬性,並對這些元素和屬性附加所需的約束,並將其保留在某個命名空間中。(請參見 圖 1。)XML 模式將此特殊命名空間稱做 {目標命名空間},即新建的元素和屬性將駐留到的命名空間。

圖 1:XML 模式命名空間中的元素和屬性用於編寫 XML 模式文檔,

該文檔生成由用戶定義的元素和屬性並將其置於 {目標命名空間} 中。

此 {目標命名空間} 隨後用於驗證 XML 實例。

 

此 {目標命名空間} 從 XML 實例中引用,以確保實例文檔的有效性。(請參見 圖 2 。)在驗證過程當中,驗證器驗證明例中所用的元素/屬性是否存在於已聲明的命名空間中,並檢查是否對其結構和數據類型存在其餘約束。

圖 2:從 XML 模式到 XML 模式實例

限定或未限定

在 XML 模式中,咱們能夠選擇指定實例文檔是必須限定全部元素和屬性,仍是隻限定全局聲明的元素和屬性。不管作出什麼樣的選擇,都將驗證整個實例。那麼,咱們爲何有兩個選擇呢?

答案是「可管理性」。當咱們選擇 限定 時,咱們指定實例中的全部元素和屬性都必須有一個命名空間,這將加強實例的命名空間複雜性。好比,當因將某些局部聲明變爲全局聲明和/將某些全局聲明變爲局部聲明而修改了模式時,根本不會影響實例文檔。相反,若是選擇 非限定,則指定只有實例中全局聲明的元素和屬性才必須具備命名空間,從而隱藏實例的命名空間複雜性。但在此情形下,好比,當因將某些局部聲明變爲全局聲明和/將某些全局聲明變爲局部聲明而修改了模式時,將影響全部實例文檔 — 且實例再也不有效。若是試圖根據已修改的 XML 模式驗證該實例,則 XML 模式驗證器將報告驗證錯誤。所以,必須根據 XML 模式中所做的修改修正命名空間,才能從新使該實例有效。

<?xml version="1.0" encoding="US-ASCII"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:tns="http://www.library.com"
        targetNamespace="http://www.library.com"
        elementFormDefault="qualified">
    attributeFormDefault="unqualified">
    <element name="Book" type="tns:BookType" />
    <complexType name="BookType">
        <sequence>
            <element name="Title" type="string" />
            <element name="Author" type="string" />
        </sequence>
    </complexType>
</schema>

元素 <schema> 的最近子元素爲全局聲明,而其餘元素則爲局部聲明。在以上示例中, Book 和 BookType 被全局聲明,而 Title 和Author 則被局部聲明。

能夠經過將模式元素屬性 elementFormDefault 和 attributeFormDefault 設置爲 qualified 或 unqualified 表示在限定和非限定之間的選擇。

elementFormDefault   = (qualified | unqualified) :unqualified
attributeFormDefault = (qualified | unqualified) :unqualified

當將 elementFormDefault 設置爲 qualified 時,它表示在該語法的實例中,必須使用前綴或經過設置 {默認命名空間} 來顯式限定全部元素。 unqualified 設置意味着只有全局聲明的元素才 必須 被顯式限定,而局部聲明的元素 不得 被限定。在此情形下,限定一個局部聲明是錯誤的。一樣,將 attributeFormDefault 設置爲 qualified 時, 必須使用前綴顯式限定實例文檔中的全部屬性。

注意,{默認命名空間} 不該用於屬性;所以,不能使用 {默認命名空間} 聲明限定屬性。 Unqualified 好像暗示經過包含的元素位於命名空間中。這頗有趣,對吧?

在下圖中,概念符號空間相似於命名空間分區的非規範性概念。例如,若是將命名空間比做電冰箱,那麼符號空間就是冰箱中的架子。就像架子對電冰箱中的整個空間進行分區同樣,符號空間對命名空間進行分區。

命名空間中有三個主要分區:一個用於全局元素聲明,一個用於全局屬性聲明,一個用於全局類型聲明 (complexType/simpleType)。這種安排表示,全局元素、全局屬性和全局類型能夠具備相同的名稱,並能夠在 {目標命名空間} 中共存而不發生任何名稱衝突。此外,每一個全局元素和全局 complexType 擁有其本身的符號空間來包含局部聲明。

讓咱們來看看屬性對 elementFormDefault 和 attributeFormDefault 的四種可能的值組合。

情形 1: elementFormDefault=qualified, attributeFormDefault=qualified

此處,{目標命名空間} 直接包含全部元素和屬性;所以在該情形中,必須限定全部元素和屬性。

情形 2: elementFormDefault=qualified, attributeFormDefault=unqualified

 

此處,{目標命名空間} 直接包含全部元素,且這些元素的相應屬性包含在相應元素的符號空間中。所以,在該情形中,只須限定元素,而不得限定屬性,除非屬性是全局聲明的。

情形 3: elementFormDefault=unqualified, attributeFormDefault=qualified

此處,{目標命名空間} 直接包含全部屬性和僅全局聲明的元素,同時這些元素在其符號空間中包含其子元素。所以,在該情形中,只虛限定全局聲明的元素和全部屬性。

情形 4: elementFormDefault=unqualified, attributeFormDefault=unqualified

 

此處,{目標命名空間} 直接包含僅在全局聲明的元素,同時這些元素在其符號空間中包含其子元素。每一個元素在其符號空間中包含相應的屬性;所以,在該情形中,只需限定僅在全局聲明的元素和屬性。

以上各圖用於直觀說明命名空間內直接包含的內容或傳遞式包含的內容(取決於elementFormDefaultattributeFormDefault 的值)。該設置表示直接位於{目標命名空間} 中的元素/屬性必須在相應的 XML 實例中擁有一個與其關聯的命名空間,而未直接(傳遞式)位於 {目標命名空間} 中的元素/屬性不得在相應的 XML 實例中擁有一個與其關聯的命名空間。

目標命名空間和無目標命名空間

如今,咱們知道 XML 模式建立新元素和屬性並將其置於稱做 {目標命名空間} 的命名空間中。但若是在該模式中未指定 {目標命名空間} 又會怎麼樣?若是未指定屬性targetNamespace,則將不存在 {目標命名空間} — 這是合法的 —但在targetNamespace 屬性中指定一個空 URI 則是「非法」的。

例如,如下代碼無效。不能爲 {目標命名空間} 指定一個空 URI:

<schema targetNamespace="" . . .>

在此情形中,若是不存在 {目標命名空間},則如前所述,則將新建的元素和屬性保存在 {無命名空間} 中。(使用術語 {默認命名空間} 是錯誤的。)要驗證相應的 XML 實例,相應的 XML 實例必須使用 http://www.w3.org/2001/XMLSchema-instance 命名空間中的 noNamespaceSchemaLocation 屬性來引用沒有目標命名空間的 XML 模式。

結論

衷心但願此命名空間概述可以幫助您更輕鬆地遷移到 XML 模式。Oracle XML 開發人員工具包 (XDK) Namespaces in the XML 1.0 W3C 推薦標準中的 W3C 命名空間;您能夠經過使用 SAXParserFactory 和 DocumentBuilderFactory 類中的setNamespaceAware(boolean) 方法打開/關閉命名空間檢查(使用 Oracle XDK 中的 JAXP API)。

 

參考: XML 模式:瞭解命名空間   http://www.oracle.com/technetwork/cn/articles/srivastava-namespaces-098626-zhs.html

相關文章
相關標籤/搜索