1. 程式人生 > 其它 >【C# XML 】 名稱空間和 XML 框架

【C# XML 】 名稱空間和 XML 框架

內如來源:http://www.noobyard.com/article/p-ciylhgkx-dd.html

名稱空間和 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)。