DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 通過 XML Catalog 實現 XML 文件的自動化實時校驗
通過 XML Catalog 實現 XML 文件的自動化實時校驗
編輯:XML詳解     

引言

  XML Catalog 實現了根據 XSD 實時校驗 XML 文件的功能。用戶不用編寫程序,通過少量的配置就可以在編輯 XML 文件的時候得到及時的反饋(需要在 XML 編輯器進行文件的編寫),實現了實時的校驗。

  然而在實際應用中,由於環境的不同以及 XML 文件本身的不同,手動方式的配置並不能滿足需求。比如,作者在實踐中發現,在開發環境裡手動配置的 XML Catalog 是不能保存在運行環境的。而且,許多實際的 XML 的編寫方式並沒有采用標准的格式,這也給 XML Catalog 的使用帶來了很多的不便。

  本文針對以上問題,通過例子來說明如何通過擴展 XML Catalog 來實現基於 xsd 對 XML 文件的自動化實時校驗。

  XML Catalog 介紹

  XML Catalog 是基於 OASIS XML Catalog specification 標准的實現,它提出了一些關於 XML 文件如何引用外部資源的控制。Eclipse 的 WTP 提供了 XML Catalog 的功能,實現利用 schema 對 xml 文件的實時校驗功能。XML Catalog 是由來自一個或者多個 catalog 條目文件的條目組成的 xml 文件,其保存了要校驗的 xml 文件以及該文件對應的 xsd 文件的映射,在運行時可以自動將它們關聯起來,從而實現對 XML 文件的校驗。

  下面通過一個例子來說明 XML catalog 的相關概念。

  XML Catalog 相關概念介紹

 <?XML version="1.0"?> 
 <!DOCTYPE catalog 
 PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN" 
 "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> 1 
 <catalog xmlns="urn:oasis:names:tc:entity:xmlns:XML:catalog"> 2 
 <group prefer="public" xml:base="file:///usr/share/XML/" > 3 
 <public 
 publicId="-//OASIS//DTD DocBook XML V4.5//EN" 4 
 uri="docbook45/docbookx.dtd"/> 
 <system 
 systemId="http://www.oasis-open.org/docbook/XML/4.5/docbookx.dtd" 5 
 uri="docbook45/docbookx.dtd"/> 
 <system 
 systemId="docbook4.5.dtd" 6 
 uri="docbook45/docbookx.dtd"/> 
 </group> 
 </catalog> 

  DOCTYPE 表示這個文件是 OASIS XML catalog 文件。如果沒有 Internet 連接,那麼,整個 DOCTYPE 的聲明需要刪除或者注釋掉。因為 catalog 處理器會嘗試從網絡去下載 catalog.dtd 文件,顯然在沒有網絡的環境下,處理器因為找不到文件會報錯。

  catalog 元素包含了 catalog 的內容和 catalog 的命名空間標識。

  group 元素是一個包裝元素,可以設置在這個組裡面包含的所有 catalog 條目的屬性。屬性 prefer="public" 指出 catalog resolver(解析器) 在使用 SYSTEM 標識符之前優先使用 PUBLIC 標識符。屬性 xml:base 表明,所有 URI 都是相對這個路徑。本例中,uri="docbook45/docbookx.dtd"/ 是個相對路徑,絕對路徑應該是 file:///usr/share/XML/ docbook45/docbookx.dtd "。

  public 元素將 publicId 映射到 uri 的路徑。publicId 是資源的一個唯一標識,通常是該文件的命名空間 .

  system 元素將 systemId 映射到 uri 的路徑。systemId 與 publicId 一樣,也是資源的唯一標識,通常是資源文件在文件系統的全路徑。

  XML Catalog 原理

  XML Catalog 提供了一種重新定位資源的機制,可以將 xml 引用的 artifacts,包括 URI 地址以及 namespace 名重新定位到另一個地址。通常這種機制被用來將遠程的引用資源重定位到本地或者 web。XML catalog 就是一個描述外部實體引用和本地緩存的相同實體的映射的文件。

  在實際的開發生產中,xml 文件經常會引用外部的文件,這些文件通常通過 URI 表示,其中以 URL 應用最廣。但是如果是絕對的 URL, 那麼只有當你的網絡能夠訪問它時才能起作用,如果網絡出現問題,那麼將不能訪問。當是相對 URL 時,例如"../../xml/dtd/docbookx.XML",只有當你的文件系統和定義者一致的時候才能起作用。

  一種解決辦法就是通過實體解析器(Entity Resolver)或者是 URI 解析器 (URI Resolver ),解析器可以通過檢查資源的 URI 來定位資源。 用戶通過配置 xml catalog, 手動的指定 xml 文件引用的 xsd 文件的本地地址,URI 解析器通過 xml catalog 裡面的映射,找到對應的 xsd, 最後 xml catalog 處理器通過解析器找到的 xsd 對 XML 進行校驗。

  通俗點說,XML catalog 通過命名空間將 XML 文件及其對應的 xsd 文件聯系起來,並通過解析器定位 xsd 文件的位置,最後通過處理器進行校驗。

  與 Javax.xml.validation 通過 xsd 對 xml 進行校驗的方法不同,xml catalog 可以通過 Namespace 來校驗所有引用這個 xsd 的 xml 文件,從而達到批量校驗的效果。例如,a.xml,b.xml,c.XML 都是由 d.xsd 校驗,那麼只要將 d.xsd 的命名空間配置好,通過該命名空間就可以校驗以上三個文件了。

  手動方式配置 XML Catalog

  手動配置 XML Catalog 比較簡單也比較容易理解,可以在 Eclipse 的開發環境中直接進行。選擇 File -> New -> Other -> Examples -> Editing and Validating XML files,便可以進行配置了。如下圖所示:

圖 1. 打開 XML Catalog 的配置界面
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  從圖 1 中可以看到有兩種 XML catalog entity , 用戶定義的實體及插件的實體。用手動方式生成的配置屬於用戶配置的實體。

圖 2. 新建一個 XML Catalog Entry
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  新建一個 XML Catalog Entry 中的 Location 指明了 xsd 文件的位置,在這裡我們選擇來源於工作空間。

圖 3. 從工作空間選擇 student.xsd 文件
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  選擇 OK 以後,XML Catalog Entry 就創建完成了。XML Catalog 會自動填寫其他兩個屬性,如下圖所示。

圖 4. 完整的 XML Catalog Entry
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  如圖所示,Location 標簽指定了 xsd 的位置,在這裡是工作空間的相對路徑;Key Type 標簽表明了在這裡我們使用的是命名空間的名字作為 xml 和 xsd 的關聯;Key 標簽的值是 XML 命名空間的值。

圖 5. 完整的 XML Catalog Entry
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  從圖 5 中可以看出,新建的 XML Catalog Entry 已經在 User Specified EntrIEs 目錄下。圖 1 到 4 顯示了 XML Catalog 的手動配置步驟。下面,我們在 XML 編輯器裡打開一個 xml 文件,看一下 XML Catalog 的功能。

圖 6. 正確的 XML 文件
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  首先,用 XML 編輯器打開 sample.XML 文件。

圖 7. XML Catalog 的實時校驗結果

  將 name 為 BB 的學生的 age 標簽去調,從圖中可以看到在編輯器的右邊有一個紅色的點,同時在 student 元素下面有個紅色的波浪線,提示 student 元素有錯誤。這是,將鼠標移到 student 元素上,可以看到具體的提示信息,student 元素不完整,缺少 age 元素。

  可以看出,應用 XML Catalog 對 XML 文件進行實時校驗,配置步驟比較簡單,只需提供相應的 xsd 文件及位置,就能將他們關聯起來,實現自動的校驗。

  擴展 XML Catalog Contributions

  在實踐中發現,如果通過上一節介紹的手動方式在 Eclipse 開發環境配置 xml catalog,那麼這些配置並不會在運行環境生效。然而通常情況下,我們需要的是運行環境的配置。比如我們要開發一些小工具,可以讓用戶編輯 xml 文件,同時我們內置了一些 xsd 文件來校驗用戶編輯的 xml 文件是不是正確。因為不能讓用戶在使用產品的時候再重新配置(因為對用戶來說,他們並不需要知道這些 xsd 的存在,還有就是,不能增加用戶的負擔)。所以,我們需要在開發環境配置好 xsd 的信息,並讓這些配置在運行時生效。通過調研,我們發現,如果要在運行環境中直接使用開發環境的配置,那麼需要擴展 XML catalog Contributions 這個擴展點。

  下面我們就一步步的演示如何在 Eclipse 插件裡擴展 XML Catalog Contributions 擴展點。

  1.打開 plugin.XML 文件的 Extensions 標簽,點擊 Add 按鈕,添加擴展點。

圖 8. 添加擴展點
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  2.在 Extension Point filter 文本框裡輸入擴展點的名字,org.eclipse.wst.XML.core.catalogContributions,並選中該擴展點,點擊 OK 按鈕。

圖 9. 選中擴展點
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  圖 10 展示了成功添加擴展點後的 Extension 頁面。

圖 10. 成功添加擴展點
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  3.新建一個 catalogContribution

圖 11. 新建 catalogContribution
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  4.新建一個 public

圖 12. 新建 public
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  5.填寫 public 的屬性信息。public 有兩個屬性,publicId 和 uri。

  publicId 就是命名空間(namespace),uri 就是 xsd 文件的物理位置,可以通過 Browse 按鈕來選擇 xsd 文件。

圖 13. 填寫 public 詳細信息
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  通過以上 5 步,就完成了對 xml catalog Contributions 的擴展。圖 14 就是完成以上配置以後的 plug.XML 文件內容。從這個文件我們可以清楚地看清楚擴展的相應配置。

圖 14. plugin.XML 文件
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  從圖 15 可以看出,與手工方式的配置不同,在運行時的環境裡,User Specified EntrIEs 裡面並沒有內容。

圖 15. 運行環境的 XML Catalog 配置
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  將 sample.xml 改錯,可以看見 XML Catalog 的提示信息。

圖 16. sampe.XML 文件
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  通過以上的步驟,我們演示了,如何擴展 XML Catalog。在下一個部分,我們將會演示如何擴展 URI Resolver 實現特殊 XML 文件的校驗。

  擴展 URI Resolver

  XML Catalog 雖然提供了比較強大的功能,但是由於實際生產環境的復雜性,一些 xml 文件並不能由其進行校驗。比如,有些 xml 文件,由於書寫不規范,並沒有命名空間,還有些 xml 文件,由於應用環境的原因,其使用了 xsi:schemaLocation 元素,將引用的 xsd 文件直接定位到了虛擬的路徑,導致 xml catalog 的定位功能失效 . 對於第一種情況,由於 XML Catalog 的設計理念就是通過命名空間進行 xml 和 xsd 的關聯,所以,不支持此種情況。對於第二中情況,我們可以通過擴展 XML Catalog 來實現。

  在擴展 URI Resolver 之前,我們對 XML Catalog 可以處理的 xml 和 xsd 的類型進行了分類,以便大家能夠清楚地知道 XML Catalog 可以解決哪些問題。

xsd \ XML 有命名空間 無命名空間 有命名空間,無 xsi:schemaLocation 可以 不可以 有命名空間,有 xsi:schemaLocation,且其值是 xsd 實際存在的位置 可以 不可以 有命名空間,有 xsi:schemaLocation,且其值不是 xsd 實際存在的位置 可以 不可以 無命名空間 
不可以 不可以

  URI Resolver 簡介

  URIResolver 負責資源的定位,XML Catalog 的處理器根據 URIResolver 的資源位置找到相應的 xsd,然後進行校驗。

  特殊的 XML 文件

  如圖 18 所示,sample.xml 文件裡中有一個 xsi:shemaLocation 屬性,它將 xsd 的位置定位到 http://www.sample.com/sample/schemas/student.xsd。正常情況下,XML Catalog 會到該位置去找 xsd, 然而,在本文中這是一個無效的地址,所以 XML Catalog 會因為找不到 xsd 而不起作用。

圖 18. 帶有 schemaLocation 標簽的 XML 文件
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  擴展 org.eclipse.wst.common.uriresolver.resolverExtensions

  resolverExtensions 擴展點可以讓用戶注冊自己的 URI Resolver,從而達到擴展默認 Resolver 的功能的作用。與默認的 Resolver 一樣,用戶擴展的 Resolver 也可以被編輯器,校驗器和向導調用。

圖 17. 添加擴展點 resolverExtensions
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  如下圖所示,該擴展點有三個屬性,class(類名), stage(階段)和 priority(優先級)。Class 指定了實現 org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver 接口的類;stage 指定了在哪個階段運行 resolver(解析器),有三個值,分別是 prenormalization, postnormalization 和 physical,默認是 physical。Prenormalization 表示解析器在輸入參數的格式統一之前運行,postnormalization 表示解析器在輸入參數的格式統一之前運行,physical 表示在所有的 pre 和 postnormalization 解析器之後運行。Priority 指定了在處在相同 stage 的解析器的執行優先級。優先級分為 high(高級),medium(中級)和 low(低級)三種,默認為中級。

圖 18. 填寫擴展點的屬性
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  下圖為增加了 resolverExtensions 擴展點的 plugin.XML 文件的內容。

圖 19. plugin.XML 文件內容
通過 XML Catalog 實現 XML 文件的自動化實時校驗

  查看原圖(大圖)

  實現 URIResolverExtension

  1.首先,在插件中新建一個類,實現 URIResolverExtension 接口。URIResolverExtension 接口提供了 resolve 方法,用來重新定位 xsd 資源,也就是找到有效的 xsd。該方法的參數有四個,第一個類型為 IFile,是在工作空間 (workspace) 中的文件,第二個參數是 String baseloaction,它是該文件在文件系統的絕對路徑,第三個參數是 publicId,它是該文件的命名空間,最後一個參數是 String systemid,它是文件的實際路徑,對於 xml 文件來說,它的 systeid 為空。但是因為我們在第 2 小節擴展了 XML Catalog, 所以,對於在 XML Catalog 文件裡面配置好的 publicId,它的 systemId 就是該文件裡面 Uri 的值,也就是 xsd 文件的實際路徑。該函數的返回值就是 XML 文件引用的 xsd 文件的位置。

清單 1. 實現 URIResolverExtension 接口

 public class MyURIResolverExtension implements URIResolverExtension { 
 
 public MyURIResolverExtension() { 
 } 
 
 @Override 
 public String resolve(IFile file, String baseLocation, String publicId, 
 String systemId) { 
 return null; 
 } 
 
 } 

清單 2. 添加 catalog 到 catalog manager

 ICatalog catalog = XMLCorePlugin.getDefault().getDefaultXMLCatalog(); 
if (catalog == null) { 
  return null; 
 } 

清單 3. 重新定位資源

 if (myResolved == null) { 
 if (publicId != null) { 
 if ((systemId != null && systemId.endsWith("student.xsd"))) //$NON-NLS-1$ 
 { 
 try { 
 int index = systemId.lastIndexOf("/"); 
 if (index > -1) 
 
   systemId = systemId.substring(index); 
 myResolved = catalog.resolvePublic(publicId, systemId); 
 } catch (MalformedURLException me) { 
 myResolved = null; 
 } catch (IOException IE) { 
 myResolved = null; 
 } 
 } 
 } 
 } 

  由清單 3 可以看出,我們通過 catalog manager 的 resolvePublic 方法,通過 publicId 找到 Catalog 裡與 publicId 對應 uri 的值,這個值就是 xsd 文件的路徑。

  小結

  本文首先介紹了 XML Catalog 相關概念以及基本原理,使讀者對其有了初步的認識。接著通過一個簡單的例子介紹了手動方式配置 XML Catalog 的步驟,使讀者有了進一步的了解。最後,通過擴展 XML Catalog 和 URI Resolver 兩個擴展點來實現比較高級的功能,使讀者對該技術有了深入的了解。XML Catalog 是比較通用的解決 XML 實時校驗問題的方法,尤其與 XML Catalog 和 URI Resolver 兩個擴展點的結合在解決一些特殊的 XML 文件的實時校驗問題時,往往能取得事半功倍的效果。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved