PostgreSQL XML類型

2021-08-26 17:00 更新
8.13.1. 創(chuàng)建XML值
8.13.2. 編碼處理
8.13.3. 訪問XML值

xml數(shù)據(jù)類型可以被用來存儲(chǔ)XML數(shù)據(jù)。它比直接在一個(gè)text域中存儲(chǔ)XML數(shù)據(jù)的優(yōu)勢(shì)在于,它會(huì)檢查輸入值的結(jié)構(gòu)是不是良好,并且有支持函數(shù)用于在其上執(zhí)行類型安全的操作,參見第 9.15 節(jié)。使用這種數(shù)據(jù)類型要求在安裝時(shí)用configure --with-libxml選項(xiàng)編譯。

xml類型可以存儲(chǔ)格式良好的遵循XML標(biāo)準(zhǔn)定義的文檔,以及內(nèi)容片段,它是通過引用更寬泛的document node XQuery 和 XPath 數(shù)據(jù)模型來定義的。 大致上說,這意味著內(nèi)容片段中可以有多于一個(gè)的頂層元素或字符節(jié)點(diǎn)。 表達(dá)式xmlvalue IS DOCUMENT可以被用來評(píng)估一個(gè)特定的xml值是一個(gè)完整文檔或者僅僅是一個(gè)文檔片段。

xml 數(shù)據(jù)類型的限制和兼容性說明可以在 第 D.3 節(jié)中找到.

8.13.1. 創(chuàng)建XML值

要從字符數(shù)據(jù)中生成一個(gè)xml類型的值,可以使用函數(shù)xmlparse:

XMLPARSE ( { DOCUMENT | CONTENT } value)

例子:

XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')

然而根據(jù)SQL標(biāo)準(zhǔn)這是唯一將字符串轉(zhuǎn)換為XML值的方法,PostgreSQL特有的語法:

xml '<foo>bar</foo>'
'<foo>bar</foo>'::xml

也可以被使用。

即便輸入值指定了一個(gè)文檔類型聲明(DTD),xml類型也不根據(jù)DTD來驗(yàn)證輸入值。目前也沒有內(nèi)建的支持用于根據(jù)其他XML模式語言(如XML模式)來進(jìn)行驗(yàn)證。

作為一個(gè)逆操作,從xml產(chǎn)生一個(gè)字符串可以使用函數(shù)xmlserialize:

XMLSERIALIZE ( { DOCUMENT | CONTENT } value AS type )

type可以是 character、character varyingtext(或者其中之一的一個(gè)別名)。再次地,根據(jù)SQL標(biāo)準(zhǔn),這也是在xml類型和字符類型間做轉(zhuǎn)換的唯一方法,但是PostgreSQL也允許你簡(jiǎn)單地造型這些值。

當(dāng)一個(gè)字符串不是使用XMLPARSE造型成xml或者不是使用XMLSERIALIZExml造型得到,對(duì)于DOCUMENTCONTENT兩者的選擇是根據(jù)XML option 會(huì)話配置參數(shù)決定的,它可以使用標(biāo)準(zhǔn)命令來設(shè)置:

SET XML OPTION { DOCUMENT | CONTENT };

或者是更具有PostgreSQL風(fēng)格的語法

SET xmloption TO { DOCUMENT | CONTENT };

默認(rèn)值是CONTENT,因此所有形式的XML數(shù)據(jù)都被允許。

8.13.2. 編碼處理

在客戶端、服務(wù)器以及其中流過的XML數(shù)據(jù)上處理多字符編碼時(shí)必須要注意。在使用文本模式向服務(wù)器傳遞查詢以及向客戶端傳遞查詢結(jié)果(在普通模式)時(shí),PostgreSQL將所有在客戶端和服務(wù)器之間傳遞的字符數(shù)據(jù)轉(zhuǎn)換為目標(biāo)端的字符編碼,參見第 23.3 節(jié)。這也包括了表示XML值的串,正如上面的例子所述。這也通常意味著由于字符數(shù)據(jù)會(huì)在客戶端和服務(wù)器之間傳遞時(shí)被轉(zhuǎn)換成其他編碼,包含在XML數(shù)據(jù)中的編碼聲明可能是無效的,因?yàn)閮?nèi)嵌的編碼聲明沒有被改變。為了處理這種行為,包含在表示xml類型輸入的字符串中包含的編碼聲明會(huì)被忽略,并且其內(nèi)容被假定為當(dāng)前服務(wù)器的編碼。接著,為了正確處理,XML數(shù)據(jù)的字符串必須以當(dāng)前客戶端編碼從客戶端發(fā)出??蛻舳素?fù)責(zé)在把文檔發(fā)送給服務(wù)器之前將它們轉(zhuǎn)換為當(dāng)前客戶端編碼,或者適當(dāng)?shù)卣{(diào)整客戶端編碼。在輸出時(shí),xml類型的值將不會(huì)有一個(gè)編碼聲明,并且客戶端將會(huì)假設(shè)所有數(shù)據(jù)都是當(dāng)前客戶端編碼。

在使用二進(jìn)制模式傳送查詢參數(shù)給服務(wù)器以及傳回查詢結(jié)果給客戶端時(shí),不會(huì)執(zhí)行編碼轉(zhuǎn)換,因此情況就有所不同。在這種情況下,XML數(shù)據(jù)中的編碼聲明將被注意到,并且如果缺少編碼聲明時(shí)該數(shù)據(jù)會(huì)被假定為UTF-8(由于XML標(biāo)準(zhǔn)的要求,注意PostgreSQL不支持UTF-16)。在輸出時(shí),數(shù)據(jù)將會(huì)有一個(gè)編碼聲明來指定客戶端編碼,除非客戶端編碼為UTF-8(這種情況下編碼聲明會(huì)被忽略)。

不用說,在PostgreSQL中處理XML數(shù)據(jù)產(chǎn)生錯(cuò)誤的可能性更小,并且在XML數(shù)據(jù)編碼、客戶端編碼和服務(wù)器編碼三者相同時(shí)效率更高。因?yàn)閄ML數(shù)據(jù)在內(nèi)部是以UTF-8處理的,如果服務(wù)器編碼也是UTF-8時(shí),計(jì)算效率將會(huì)最高。

小心

當(dāng)服務(wù)器編碼不是UTF-8時(shí),某些XML相關(guān)的函數(shù)可能在非ASCII數(shù)據(jù)上完全無法工作。尤其在xmltable()xpath()上,這是一個(gè)已知的問題。

8.13.3. 訪問XML值

xml數(shù)據(jù)類型有些不同尋常,因?yàn)樗惶峁┤魏伪容^操作符。這是因?yàn)閷?duì)于XML數(shù)據(jù)不存在良定義的和通用的比較算法。這種狀況造成的后果就是,你無法通過比較一個(gè)xml和一個(gè)搜索值來檢索行。XML值因此通常應(yīng)該伴隨著一個(gè)獨(dú)立鍵值域,如一個(gè)ID。另一種比較XML值的方案是將它們先轉(zhuǎn)換為字符串,但注意字符串比較對(duì)于XML比較方法沒有什么幫助。

由于沒有可以用于xml數(shù)據(jù)類型的比較操作符,因此無法直接在這種類型上創(chuàng)建索引。如果需要在XML中快速的搜索,可能的解決方案包括將表達(dá)式造型為一個(gè)字符串類型然后索引之,或者在一個(gè)XPath表達(dá)式上索引。當(dāng)然,實(shí)際的查詢必須被調(diào)整為使用被索引的表達(dá)式。

PostgreSQL中的文本搜索功能也可以被用來加速XML數(shù)據(jù)的全文搜索。但是,所需的預(yù)處理支持目前在PostgreSQL發(fā)布中還不可用。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)