XMLCatalog 是公共資源的目錄,例如在 XML 文件中引用的 DTD 或實體。目錄通常用於讓 Web 參考資源指向資源的本地快取副本。
這允許 XML 分析器、XSLT 處理器或其他 XML 文件使用者有效地允許本地替換 Web 上提供的資源。
注意:此工作會使用,但不會依賴 Apache Ant 發行版中未包含的外部程式庫。請參閱 程式庫依賴關係 以取得更多資訊。
此資料類型提供基於 OASIS XML 目錄標準 的資源位置目錄。目錄項目用於實體解析和 URI 解析,這符合 Java API for XML 處理 (JAXP) 規格 中定義的 org.xml.sax.EntityResolver
和 javax.xml.transform.URIResolver
介面。
例如,在 web.xml
檔案中,DTD 參照為
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
XML 處理器在沒有 XMLCatalog 支援的情況下,需要從指定的 URL 擷取 DTD,只要需要驗證文件時。
這在建置過程中可能會非常耗時,特別是在網路傳輸量受限的情況下。或者,您可以執行下列操作
<xmlcatalog>
,其中包含一個 <dtd>
元素,其 location 屬性指向該檔案。XMLCatalog 可以出現在支援此功能的工作中,或與 target
位於同一層級,亦即,作為 project
的子項目,以便在不同工作中重複使用,例如 XML 驗證和 XSLT 轉換。XML 驗證工作使用 XMLCatalog 進行實體解析。XSLT 轉換工作同時使用 XMLCatalog 進行實體和 URI 解析。
XMLCatalog 指定為對另一個 XMLCatalog 的參考(先前在建置檔案中定義),或指定為 dtd
或 entity
位置的清單。此外,外部目錄檔案可以指定在巢狀 catalogpath
中,但除非 xml-commons 的解析器程式庫可在系統類別路徑中使用,否則將會忽略這些檔案。由於在解析器 1.0 發布後解析器程式碼中發生向後不相容的變更,因此 Ant 只支援解析器 1.1 或更新版本。實體解析的個別類別路徑可以透過巢狀 classpath
元素內嵌指定;否則,系統類別路徑也會用於此目的。
XMLCatalog 也可以巢狀在其他 XMLCatalog 內。例如,可以透過包含幾個巢狀 XMLCatalog 來建立一個「超集」XMLCatalog,這些巢狀 XMLCatalog 參照其他先前定義的 XMLCatalog。
資源位置可以內嵌指定,或在外部目錄檔案中指定,或同時使用這兩種方式。為了使用外部目錄檔案,xml-commons 解析器程式庫 (resolver.jar) 必須在您的路徑中。外部目錄檔案可以是 純文字格式 或 XML 格式。如果在類別路徑中找不到 xml-commons 解析器程式庫,則在 catalogpath
中指定的外部目錄檔案將會被忽略,並會記錄警告。然而,在此情況下,內嵌項目的處理將會正常進行。
目前,只有 <dtd>
和 <entity>
元素可以內嵌指定;這些元素大致分別對應於 OASIS 目錄項目類型 PUBLIC
和 URI
。相對地,外部目錄檔案可以使用 OASIS 規格 中定義的任何項目類型。
當 XML 處理器查詢實體、DTD 或 URI 時,XMLCatalog 會搜尋其條目清單,查看是否有任何相符項。也就是說,它會嘗試比對每個條目的 publicId 屬性,以及要解析實體的 PublicID 或 URI。假設找到相符的條目,XMLCatalog 接著會執行下列步驟
首先會在檔案系統中查詢 location。如果 location 是相對路徑,則會使用 Ant 專案 basedir 屬性作為基本目錄。如果 location 指定絕對路徑,則會原樣使用。一旦我們取得絕對路徑,我們會檢查該路徑是否存在有效且可讀取的檔案。如果存在,我們就完成了。如果不存在,我們會繼續執行下一步。
接著會在類別路徑中查詢 location。請回想一下,jar 檔案只是精美的 zip 檔案。對於類別路徑查詢,location 會原樣使用(不會預先加上基底)。我們會使用 Classloader 嘗試從類別路徑載入資源。例如,如果 hello.jar 在類別路徑中,且其中包含 foo/bar/blat.dtd,它會解析 location 為 foo/bar/blat.dtd 的實體。當然,它不會解析 location 為 blat.dtd
的實體。
接下來會發生什麼事,取決於 xml-commons 中的解析器函式庫是否在類別路徑中可用。如果是,我們會將所有進一步的解析嘗試都遞延給它。解析器函式庫支援極為精密的函式,例如 URL 重寫等,可以透過在外部目錄檔案中建立適當的條目來存取(XMLCatalog 尚未提供所有在 OASIS 標準 中定義條目的內嵌支援)。
最後,我們會嘗試將 location 變成 URL。一開始這看起來似乎會違背 XMLCatalog 的目的,為什麼要再回到網際網路上?但事實上,這可以用於(在某種程度上)實作 HTTP 重新導向,將一個 URL 替換為另一個 URL。對應到的 URL 也可能由本機網路伺服器提供。如果 URL 解析為有效且可讀取的資源,我們就完成了。否則,我們就放棄。在這種情況下,XML 處理器會執行其正常的解析演算法。根據處理器組態,進一步的解析失敗可能會導致致命(即會終止建置)錯誤,也可能不會。
屬性 | 說明 | 必要 |
---|---|---|
id | XMLCatalog 的唯一名稱,用於從另一個 XMLCatalog 參照 XMLCatalog 的內容 | 否 |
refid | 您希望用於此 XMLCatalog 的另一個 XMLCatalog 的 id | 否 |
用於指定 XMLCatalog 的 dtd
和 entity
元素在結構上相同
屬性 | 說明 | 必要 |
---|---|---|
publicId | 定義 dtd 或實體時使用的公開識別碼,例如 "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" |
是 |
location | 要針對指定的公開識別碼使用的本地替換位置。這可以指定為檔名、在類別路徑中找到的資源名稱或 URL。相對路徑會根據預設為 Ant 專案 basedir 的基準解析。 | 是 |
要使用於 實體解析 的類別路徑。巢狀的 <classpath>
是類似 路徑 的結構。
巢狀的 catalogpath
元素是類似 路徑 的結構,列出要搜尋的目錄檔。此路徑中的所有檔都假設為 OASIS 目錄檔,採用 純文字格式 或 XML 格式。指定不存在檔的項目會被忽略。如果 xml-commons 中的解析程式庫在類別路徑中不可用,所有 catalogpath
都會被忽略,並記錄警告。
設定 XMLCatalog,其中包含一個在使用者家目錄中本地參照的 DTD
<xmlcatalog> <dtd publicId="-//OASIS//DTD DocBook XML V4.1.2//EN" location="/home/dion/downloads/docbook/docbookx.dtd"/> </xmlcatalog>
設定 XMLCatalog,其中包含多個 DTD,可以在檔案系統(相對於 Ant 專案 basedir)或類別路徑中找到
<xmlcatalog id="commonDTDs"> <dtd publicId="-//OASIS//DTD DocBook XML V4.1.2//EN" location="docbook/docbookx.dtd"/> <dtd publicId="-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" location="web-app_2_2.dtd"/> </xmlcatalog>
設定 XMLCatalog,其中包含 DTD 和實體的組合,以及巢狀的 XMLCatalog 和兩種格式的外部目錄檔
<xmlcatalog id="allcatalogs"> <dtd publicId="-//ArielPartners//DTD XML Article V1.0//EN" location="com/arielpartners/knowledgebase/dtd/article.dtd"/> <entity publicId="LargeLogo" location="com/arielpartners/images/ariel-logo-large.gif"/> <xmlcatalog refid="commonDTDs"/> <catalogpath> <pathelement location="/etc/sgml/catalog"/> <fileset dir="/anetwork/drive" includes="**/catalog"/> <fileset dir="/my/catalogs" includes="**/catalog.xml"/> </catalogpath> </xmlcatalog> </xmlcatalog>
在 xslt
工作中參照上述 XMLCatalog
<xslt basedir="${source.doc}" destdir="${dest.xdocs}" extension=".xml" style="${source.xsl.converter.docbook}" includes="**/*.xml" force="true"> <xmlcatalog refid="allcatalogs"/> </xslt>