使用原生XML(native XML)特性處理不斷變化的數據結構
在處理不完全符合關系模型要求的數據或者應用程序必須處理隨時間而改變的數據結構時
你會怎麼做呢?
在本專欄中
我將闡明我是如何使用Oracle XML DB的特性來創建一個原型系統的
它無需重新編碼便能適應新的及改變了的數據結構
我還將介紹Oracle的DevTrends網站上的工作示例代碼
Oracle XML DB是Oracle
i第二版(
或更高版)的一組特性
它為存儲
定位和查詢XML文檔提供了原生支持
應用程序要求 該原型系統將存儲並轉發政府機構所使用的管理文檔(表格
狀態報告
簡報等)
很高興這些文檔將用XML進行編碼
但仍存在著一系列難以應對的需求
這些文檔的數量
類型及內容經常改變
該系統必須同時處理新舊兩種文檔類型
這些文檔有時含有多信息文本(rich text)
包括HTML標記
數據是在多個不同位置輸入的
所以我需要信息域幫助解決數據分布問題
將來系統遲早要支持數字簽名
設計要點 即使該系統處理的文檔類型會隨時間變化
我仍然希望能夠在存儲XML文檔時對它們進行驗證
因此
每一種文檔類型都需要對定義它的相應XML模式進行注冊
使用Oracle
i XML DB可以將XML文檔分解成關系對象(結構化存儲)或者只是將這些文檔整個存儲為CLOB(非結構化存儲)
兩種方法都利用了原生的XMLType服務器類型
從而支持XPath表達式與訪問方法
因為該系統必須能夠適應新的文檔類型而不需改變代碼
所以文檔將存儲為CLOB
但只存儲XML文檔自身是不夠的
處理文檔驗證的代碼庫以及系統的持久性
同步和管理取決於某些其他數據元素
如全局主關鍵字
日期/時間標記
最初位置及正在處理的文檔類型
這些元素
即文檔屬性
必須與在不同位置間發送的XML文檔共存
所以需要一個屬性模式來包含它們
有兩種方法可以將XML文檔同文檔屬性關聯起來
一種是簡單地將文檔屬性元素包含在各個文檔模式之中
這種方法提供了一種相當扁平的結構
它使XPath表達式較短
但我卻不能處理別人創建的模式
另一種方法是將XML文檔包裝在另一個含有所需屬性的XML文檔中
這種方法需要分別驗證包裝文檔和內容文檔
但它會提供所需要的靈活性
創建XML模式 我的工作將從創建既能表示包裝文檔又能表示內容文檔的XML模式開始
首先從包裝文檔開始
創建一個XML模式
它包含所需的全部文檔屬性和一個用於內容文檔的占位符(利用任一元素類型)
所有的文檔屬性都根據
屬性
元素進行分組
我可以用KeyName元素為文檔命名以便檢索
Schema和Element元素指示Content元素中所包含的文檔類型
通過Oracle
i XML DB
可以使用一組特定的模式注釋對設置內部存儲的方式進行定制
我可以指定每個元素的存儲類型
為所創建的表和類型提供數據庫名
在這樣的情況下
我想混合使用結構化的XML文檔存儲與非結構化的XML文檔存儲
將內容存儲為原生XML
將文檔屬性存儲為對象關系類型
我將為DOCUMENTS設定defTable屬性
並給出各Properties元素的SQLName值
對於Content元素
我打算將存儲類型設為CLOB
它表示非結構化的XML存儲
當此模式向數據庫注冊時
XML DB將依照模式注釋創建對象關系類型
接下來
為了驗證置於Content元素中的文檔的各個類型
還需要為各個文檔類型准備一個XML模式
我想跟蹤該系統所能處理的所有內容類型
所以我會創建一個存儲程序來注冊內容模式
該程序會記錄內容類型名和TYPES表中的其他細節
然後向XML DB注冊該模式
因為我在上一步中已經為這些文檔創建了CLOB存儲
所以當我使用該程序為內容注冊任何一種模式時
該程序都會告訴XML DB不要創建任何新表或對象類型
Dbms_xmlschema
registerSchema(
schemaURL => schema_url
schemaDoc => schema
local => true
genTypes => false
genTables => false)
插入數據 現在我將插入一個新文檔
為了更輕松
我要創建一個存儲程序
它將
)檢查文檔內容是否已注冊
)驗證文檔
)用一般XML包裝文件包裝文檔
並填充屬性元素
)將文檔插入數據庫
要插入一個新文檔
只需要像下面這樣調用該程序
dtx_doc
save(xmltype(
getDocument(
incident
xml
))
Incident
)
getDocument()調用是一個實用程序
它基於Oracle
i XML數據庫開發人員指南附錄G中的示例代碼
它作為一個CLOB從文件系統載入文檔
第二個參數save()的代表KeyName元素
將被用於在文檔上建立索引
一個突出的XML DB特性是能夠在XML
文檔存儲表上創建基於函數的索引
如下所示
CREATE INDEX ix_keyname
ON documents d (d
extractValue(
/Document/Properties/KeyName
));
檢索數據 現在可以對DOCUMENTS表運行基於XPath的查詢
但如果創建一個XML文檔存儲的關系視圖
如清單
所示
就能通過標准SQL來訪問結構化的存儲
那麼查詢就會更容易
這樣也可以更輕松地查詢文檔屬性
現在可以直接查詢該視圖
以查看文檔屬性
清單
中的Print_table()過程是Tom Kyte()編寫的一個實用程序
它可對查詢進行縱向格式化
它與本專欄的示例代碼一起放在了網上
除了通過SQL調用檢索數據外
也可以利用內建於該數據庫中的Oracle XML DB HTTP協議服務器檢索文檔
如果你的數據庫監聽程序正在運行
你可以在浏覽器中輸入以下URL
以查看插入文檔的完整XML
//localhost:
/oradb/
DTXDOCS/DOCUMENTS
DTXDOCS是我的數據庫用戶名
我也可以在URL中置入一個XPath查詢
並指定一個XML樣式表
它會把XML轉換為格式優美的HTML文檔
//localhost:
/oradb/DTXDOCS/
DOCUMENTS/ROW/Document
[Properties/Subject=
Incident
]
?transform=/public/dtxdocs/incident
xslt
&contenttype=text/html
示例代碼 在DevTrends網站上
我已經放置了用於說明本文簡述概念的示例代碼
其中的說明腳本會告訴你我創建用於應用程序的內部工作的單一代碼庫以及根據需要向系統注冊新文檔類型的方法
由於我在實際文檔中沒有使用結構化的存儲
所以這種方法也可能多少會有助於解決模式發展的問題
Cameron O
Rourke (camero) 擔任Oracle 技術專家已超個
年
From:http://tw.wingwit.com/Article/program/Oracle/201311/17623.html