W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
本節(jié)中描述的函數(shù)以及類函數(shù)的表達(dá)式都在類型xml
的值上操作。類型xml
的詳細(xì)信息請(qǐng)參見第 8.13 節(jié)。用于在值和類型xml
之間轉(zhuǎn)換的類函數(shù)的表達(dá)式xmlparse
和
xmlserialize
記錄在這里,而不是在本節(jié)中。
使用大部分這些函數(shù)要求PostgreSQL使用了configure --with-libxml
進(jìn)行編譯。
有一組函數(shù)和類函數(shù)的表達(dá)式可以用來從 SQL 數(shù)據(jù)產(chǎn)生 XML 內(nèi)容。它們特別適合于將查詢結(jié)果格式化成 XML 文檔以便于在客戶端應(yīng)用中處理。
xmlcomment
xmlcomment
( text ) → xml
函數(shù)xmlcomment
創(chuàng)建了一個(gè) XML 值,它包含一個(gè)使用指定文本作為內(nèi)容的 XML 注釋。 該文本不包含“--
”或者也不會(huì)以一個(gè)“-
”結(jié)尾,否則該結(jié)果的結(jié)構(gòu)不是一個(gè)合法的
XML 注釋。如果參數(shù)為空,結(jié)果也為空。
例子:
SELECT xmlcomment('hello');
xmlcomment
--------------
<!--hello-->
xmlconcat
xmlconcat
( xml
[, ...] ) → xml
函數(shù)xmlconcat
將由單個(gè) XML 值組成的列表串接成一個(gè)單獨(dú)的值,這個(gè)值包含一個(gè) XML 內(nèi)容片斷。空值會(huì)被忽略,只有當(dāng)沒有參數(shù)為非空時(shí)結(jié)果才為空。
例子:
SELECT xmlconcat('<abc/>', '<bar>foo</bar>');
xmlconcat
----------------------
<abc/><bar>foo</bar>
如果 XML 聲明存在,它們會(huì)按照下面的方式被組合。如果所有的參數(shù)值都有相同的 XML 版本聲明,該版本將被用在結(jié)果中,否則將不使用版本。如果所有參數(shù)值有獨(dú)立聲明值“yes”,那么該值將被用在結(jié)果中。如果所有參數(shù)值都有一個(gè)獨(dú)立聲明值并且至少有一個(gè)為“no”,則“no”被用在結(jié)果中。否則結(jié)果中將沒有獨(dú)立聲明。如果結(jié)果被決定要要求一個(gè)獨(dú)立聲明但是沒有版本聲明,將會(huì)使用一個(gè)版本 1.0 的版本聲明,因?yàn)?XML 要求一個(gè) XML 聲明要包含一個(gè)版本聲明。編碼聲明會(huì)被忽略并且在所有情況中都會(huì)被移除。
例子:
SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>');
xmlconcat
-----------------------------------
<?xml version="1.1"?><foo/><bar/>
xmlelement
xmlelement
( NAME
name
[, XMLATTRIBUTES
( attvalue
[ AS
attname
] [, ...] ) ] [, content
[, ...]] ) → xml
表達(dá)式xmlelement
使用給定名稱、屬性和內(nèi)容產(chǎn)生一個(gè) XML 元素。 語法中顯示的name
和attname
項(xiàng)是簡(jiǎn)單的標(biāo)識(shí)符,而不是值。 attvalue
和content
項(xiàng)是表達(dá)式,它們可以生成任何
PostgreSQL數(shù)據(jù)類型。 XMLATTRIBUTES
的參數(shù)生成XML元素的屬性;將content
值連接起來形成其內(nèi)容。
例子:
SELECT xmlelement(name foo);
xmlelement
------------
<foo/>
SELECT xmlelement(name foo, xmlattributes('xyz' as bar));
xmlelement
------------------
<foo bar="xyz"/>
SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');
xmlelement
-------------------------------------
<foo bar="2007-01-26">content</foo>
不是合法 XML 名字的元素名和屬性名將被逃逸,逃逸的方法是將違反的字符用序列_x
替換,其中HHHH
_HHHH
是被替換字符的 Unicode 代碼點(diǎn)的十六進(jìn)制表示。例如:
SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));
xmlelement
----------------------------------
<foo_x0024_bar a_x0026_b="xyz"/>
如果屬性值是一個(gè)列引用,則不需要指定一個(gè)顯式的屬性名,在這種情況下列的名字將被默認(rèn)用于屬性的名字。在其他情況下,屬性必須被給定一個(gè)顯式名稱。因此這個(gè)例子是合法的:
CREATE TABLE test (a xml, b xml);
SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
但是下面這些不合法:
SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
如果指定了元素內(nèi)容,它們將被根據(jù)其數(shù)據(jù)類型格式化。如果內(nèi)容本身也是類型xml
,就可以構(gòu)建復(fù)雜的 XML 文檔。例如:
SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
xmlelement(name abc),
xmlcomment('test'),
xmlelement(name xyz));
xmlelement
----------------------------------------------
<foo bar="xyz"><abc/><!--test--><xyz/></foo>
其他類型的內(nèi)容將被格式化為合法的 XML 字符數(shù)據(jù)。這意味著字符 <, >, 和 & 將被轉(zhuǎn)換為實(shí)體。二進(jìn)制數(shù)據(jù)(數(shù)據(jù)類型bytea
)將被表示成 base64 或十六進(jìn)制編碼,具體取決于配置參數(shù)xmlbinary的設(shè)置。為了使PostgreSQL的映射與SQL:2006及以后的SQL:2006中指定的映射保持一致,個(gè)別數(shù)據(jù)類型的特殊行為將不斷發(fā)展,正如
第 D.3.1.3 節(jié)中討論的那樣。
xmlforest
xmlforest
( content
[ AS
name
] [, ...] ) → xml
表達(dá)式xmlforest
使用給定名稱和內(nèi)容產(chǎn)生一個(gè)元素的 XML 森林(序列)。 對(duì)于xmlelement
,每個(gè)name
都必須是一個(gè)簡(jiǎn)單的標(biāo)識(shí)符,而content
表達(dá)式可以有任何數(shù)據(jù)類型。
例子:
SELECT xmlforest('abc' AS foo, 123 AS bar);
xmlforest
------------------------------
<foo>abc</foo><bar>123</bar>
SELECT xmlforest(table_name, column_name)
FROM information_schema.columns
WHERE table_schema = 'pg_catalog';
xmlforest
------------------------------------?-----------------------------------
<table_name>pg_authid</table_name>?<column_name>rolname</column_name>
<table_name>pg_authid</table_name>?<column_name>rolsuper</column_name>
...
如我們?cè)诘诙€(gè)例子中所見,如果內(nèi)容值是一個(gè)列引用,元素名稱可以被忽略,這種情況下默認(rèn)使用列名。否則,必須指定一個(gè)名字。
如上文xmlelement
所示,非法 XML 名字的元素名會(huì)被逃逸。相似地,內(nèi)容數(shù)據(jù)也會(huì)被逃逸來產(chǎn)生合法的 XML 內(nèi)容,除非它已經(jīng)是一個(gè)xml
類型。
注意如果 XML 森林由多于一個(gè)元素組成,那么它不是合法的 XML 文檔,因此在xmlelement
中包裝xmlforest
表達(dá)式會(huì)有用處。
xmlpi
xmlpi
( NAME
name
[, content
] ) → xml
表達(dá)式xmlpi
創(chuàng)建一個(gè) XML 處理指令。 對(duì)于xmlelement
,name
必須是一個(gè)簡(jiǎn)單的標(biāo)識(shí)符,而content
表達(dá)式可以有任何數(shù)據(jù)類型。如果存在,content
不能包含字符序列
?>
。
例子:
SELECT xmlpi(name php, 'echo "hello world";');
xmlpi
-----------------------------
<?php echo "hello world";?>
xmlroot
xmlroot
( xml
, VERSION
{text
|NO VALUE
} [, STANDALONE
{YES
|NO
|NO VALUE
} ] ) → xml
表達(dá)式xmlroot
修改一個(gè) XML 值的根結(jié)點(diǎn)的屬性。如果指定了一個(gè)版本,它會(huì)替換根節(jié)點(diǎn)的版本聲明中的值;如果指定了一個(gè)獨(dú)立設(shè)置,它會(huì)替換根節(jié)點(diǎn)的獨(dú)立聲明中的值。
SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
version '1.0', standalone yes);
xmlroot
----------------------------------------
<?xml version="1.0" standalone="yes"?>
<content>abc</content>
xmlagg
xmlagg
( xml
) → xml
和這里描述的其他函數(shù)不同,函數(shù)xmlagg
是一個(gè)聚集函數(shù)。它將聚集函數(shù)調(diào)用的輸入值串接起來,非常像xmlconcat
所做的事情,除了串接是跨行發(fā)生的而不是在單一行的多個(gè)表達(dá)式上發(fā)生。聚集表達(dá)式的更多信息請(qǐng)見第 9.21 節(jié)。
例子:
CREATE TABLE test (y int, x xml);
INSERT INTO test VALUES (1, '<foo>abc</foo>');
INSERT INTO test VALUES (2, '<bar/>');
SELECT xmlagg(x) FROM test;
xmlagg
----------------------
<foo>abc</foo><bar/>
為了決定串接的順序,可以為聚集調(diào)用增加一個(gè)ORDER BY
子句,如第 4.2.7 節(jié)中所述。例如:
SELECT xmlagg(x ORDER BY y DESC) FROM test;
xmlagg
----------------------
<bar/><foo>abc</foo>
我們推薦在以前的版本中使用下列非標(biāo)準(zhǔn)方法,并且它們?cè)谔囟ㄇ闆r下仍然有用:
SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
xmlagg
----------------------
<bar/><foo>abc</foo>
這一節(jié)描述的表達(dá)式檢查xml
值的屬性。
IS DOCUMENT
xml
IS DOCUMENT
→ boolean
如果參數(shù) XML 值是一個(gè)正確的 XML 文檔,則IS DOCUMENT
返回真,如果不是則返回假(即它是一個(gè)內(nèi)容片斷),或者是參數(shù)為空時(shí)返回空。文檔和內(nèi)容片斷之間的區(qū)別請(qǐng)見第 8.13 節(jié)。
IS NOT DOCUMENT
xml
IS NOT DOCUMENT
→ boolean
如果參數(shù)中的XML值是一個(gè)正確的XML文檔,那么表達(dá)式IS NOT DOCUMENT
返回假,否則返回真(也就是說它是一個(gè)內(nèi)容片段),如果參數(shù)為空則返回空。
XMLEXISTS
XMLEXISTS ( text
PASSING [BY {REF|VALUE}] xml
[BY {REF|VALUE}] ) → boolean
函數(shù)xmlexists
評(píng)價(jià)一個(gè)XPath 1.0表達(dá)式(第一個(gè)參數(shù)),以傳遞的XML值作為其上下文項(xiàng)。 如果評(píng)價(jià)的結(jié)果產(chǎn)生一個(gè)空節(jié)點(diǎn)集,該函數(shù)返回false,如果產(chǎn)生任何其他值,則返回true。 如果任何參數(shù)為空,則函數(shù)返回null。 作為上下文項(xiàng)傳遞的非空值必須是一個(gè)XML文檔,而不是內(nèi)容片段或任何非XML值。
例子:
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>');
xmlexists
------------
t
(1 row)
BY REF
和BY VALUE
子句在PostgreSQL中被接受,但在第 D.3.2 節(jié)中被忽略。
在SQL標(biāo)準(zhǔn)中,xmlexists
函數(shù)評(píng)估XML查詢語言中的表達(dá)式,但PostgreSQL只允許使用XPath 1.0表達(dá)式,在第 D.3.1 節(jié)中討論過。
xml_is_well_formed
xml_is_well_formed
( text
) → boolean
xml_is_well_formed_document
( text
) → boolean
xml_is_well_formed_content
( text
) → boolean
這些函數(shù)檢查一個(gè)text
串是不是一個(gè)良構(gòu)的 XML,返回一個(gè)布爾結(jié)果。xml_is_well_formed_document
檢查一個(gè)良構(gòu)的文檔,而xml_is_well_formed_content
檢查良構(gòu)的內(nèi)容。如果xmloption配置參數(shù)被設(shè)置為
DOCUMENT
,xml_is_well_formed
會(huì)做第一個(gè)函數(shù)的工作;如果配置參數(shù)被設(shè)置為CONTENT
,xml_is_well_formed
會(huì)做第二個(gè)函數(shù)的工作。這意味著xml_is_well_formed
對(duì)于檢查一個(gè)到類型xml
的簡(jiǎn)單造型是否會(huì)成功非常有用,而其他兩個(gè)函數(shù)對(duì)于檢查
XMLPARSE
的對(duì)應(yīng)變體是否會(huì)成功有用。
例子:
SET xmloption TO DOCUMENT;
SELECT xml_is_well_formed('<>');
xml_is_well_formed
--------------------
f
(1 row)
SELECT xml_is_well_formed('<abc/>');
xml_is_well_formed
--------------------
t
(1 row)
SET xmloption TO CONTENT;
SELECT xml_is_well_formed('abc');
xml_is_well_formed
--------------------
t
(1 row)
SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</pg:foo>');
xml_is_well_formed_document
-----------------------------
t
(1 row)
SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</my:foo>');
xml_is_well_formed_document
-----------------------------
f
(1 row)
最后一個(gè)例子顯示了這些檢查也包括名字空間是否正確地匹配。
要處理數(shù)據(jù)類型xml
的值, PostgreSQL 提供了函數(shù)xpath
和xpath_exists
,它們計(jì)算 XPath 1.0 表達(dá)式以及XMLTABLE
表函數(shù)。
xpath
xpath
( xpath
text
, xml
xml
[, nsarray
text[]
] ) → xml[]
函數(shù)xpath
根據(jù) XML 值xml
計(jì)算 XPath 1.0 表達(dá)式xpath
(以文本形式給出)。 它返回一個(gè) XML 值的數(shù)組,該數(shù)組對(duì)應(yīng)于該 XPath 表達(dá)式產(chǎn)生的結(jié)點(diǎn)集合。 如果該 XPath 表達(dá)式返回一個(gè)標(biāo)量值而不是一個(gè)結(jié)點(diǎn)集合,將會(huì)返回一個(gè)單一元素的數(shù)組。
第二個(gè)參數(shù)必須是一個(gè)良構(gòu)的 XML 文檔。特殊地,它必須有一個(gè)單一根結(jié)點(diǎn)元素。
該函數(shù)可選的第三個(gè)參數(shù)是一個(gè)名字空間映射的數(shù)組。這個(gè)數(shù)組應(yīng)該是一個(gè)二維text
數(shù)組,其第二軸長(zhǎng)度等于2(即它應(yīng)該是一個(gè)數(shù)組的數(shù)組,其中每一個(gè)都由剛好 2 個(gè)元素組成)。每個(gè)數(shù)組項(xiàng)的第一個(gè)元素是名字空間的名稱(別名),第二個(gè)元素是名字空間的 URI。并不要求在這個(gè)數(shù)組中提供的別名和在 XML 文檔本身中使用的那些名字空間相同(換句話說,在 XML 文檔中和在xpath
函數(shù)環(huán)境中,別名都是
本地的
)。
例子:
SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
ARRAY[ARRAY['my', 'http://example.com']]);
xpath
--------
{test}
(1 row)
要處理默認(rèn)(匿名)命名空間,做這樣的事情:
SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
ARRAY[ARRAY['mydefns', 'http://example.com']]);
xpath
--------
{test}
(1 row)
xpath_exists
xpath_exists
( xpath
text
, xml
xml
[, nsarray
text[]
] ) → boolean
函數(shù)xpath_exists
是xpath
函數(shù)的一種特殊形式。這個(gè)函數(shù)不是返回滿足 XPath 1.0 表達(dá)式的單一 XML 值,它返回一個(gè)布爾值表示查詢是否被滿足(具體來說,它是否產(chǎn)生了空節(jié)點(diǎn)集以外的任何值)。這個(gè)函數(shù)等價(jià)于標(biāo)準(zhǔn)的XMLEXISTS
謂詞,不過它還提供了對(duì)一個(gè)名字空間映射參數(shù)的支持。
例子:
SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
ARRAY[ARRAY['my', 'http://example.com']]);
xpath_exists
--------------
t
(1 row)
xmltable
XMLTABLE
( [ XMLNAMESPACES ( namespace_uri AS namespace_name
[, ...] ), ] row_expression
PASSING
[BY {REF|VALUE}] document_expression
[BY {REF|VALUE}] COLUMNS name { type [PATH
column_expression] [
DEFAULT
default_expression] [
NOT NULL | NULL] |
FOR ORDINALITY }
[, ...]) → setof record
xmltable
表達(dá)式基于給定的XML值產(chǎn)生一個(gè)表、一個(gè)抽取行的XPath過濾器以及一個(gè)列定義集合。 雖然它在語法上類似于函數(shù),但它只能作為一個(gè)表出現(xiàn)在查詢的FROM
子句中。
可選的XMLNAMESPACES
子句是一個(gè)逗號(hào)分隔的名字空間定義列表。 其中每個(gè)namespace_uri
是一個(gè)text
表達(dá)式,每個(gè)namespace_name
是一個(gè)簡(jiǎn)單的標(biāo)識(shí)符。 它指定文檔中使用的XML名字空間極其別名。當(dāng)前不支持默認(rèn)的名字空間說明。
所需的row_expression
參數(shù)是一個(gè)求值的XPath 1.0表達(dá)式(以text
形式給出),通過傳遞XML值document_expression
作為其上下文項(xiàng),得到一組XML節(jié)點(diǎn)。 這些節(jié)點(diǎn)就是xmltable
轉(zhuǎn)換為輸出行的內(nèi)容。如果
document_expression
為空,或者row_expression
產(chǎn)生空節(jié)點(diǎn)集或節(jié)點(diǎn)集以外的任何值,則不會(huì)產(chǎn)生行。
document_expression
提供了上下文。row_expression
的項(xiàng)。 它必須是一個(gè)格式良好的XML文檔;不接受片段/森林。BY REF
和BY VALUE
子句 如上文所討論的那樣,被接受但被忽略了,正如在
第 D.3.2 節(jié)中所討論的。
在SQL標(biāo)準(zhǔn)中,xmltable
函數(shù) 評(píng)估XML查詢語言中的表達(dá)式。 但PostgreSQL只允許使用XPath 1.0的 表達(dá)式,正如在 第 D.3.1 節(jié)所討論的。
需要的COLUMNS
子句指定將在輸出表中生成的列。有關(guān)格式,請(qǐng)參閱上面的語法摘要。 每個(gè)列都需要一個(gè)名稱,作為一個(gè)數(shù)據(jù)類型(除非指定了 FOR ORDINALITY
,在這種情況下類型 integer
是隱式的)。 路徑、默認(rèn)值以及為空性子句是可選的。
被標(biāo)記為FOR ORDINALITY
的列將按照從row_expression
的結(jié)果節(jié)點(diǎn)集中檢索到的節(jié)點(diǎn)的順序,從1開始,填充行號(hào)。最多只能有一個(gè)列被標(biāo)記為FOR ORDINALITY
。
XPath 1.0 并沒有為節(jié)點(diǎn)集中的節(jié)點(diǎn)指定順序,因此依賴特定結(jié)果順序的代碼將取決于實(shí)現(xiàn)。 詳情請(qǐng)參見 第 D.3.1.2 節(jié)。
列的column_expression
是一個(gè)XPath 1.0表達(dá)式,它對(duì)每一行都要進(jìn)行求值,并以row_expression
結(jié)果中的當(dāng)前節(jié)點(diǎn)作為其上下文項(xiàng),以找到列的值。 如果沒有給出column_expression
,那么列名被用作隱式路徑。
如果一個(gè)列的XPath表達(dá)式返回一個(gè)非XML值(在XPath 1.0中僅限于string、boolean或double),而該列的PostgreSQL類型不是xml
,那么該列將被設(shè)置為將值的字符串表示法分配給PostgreSQL類型。 (如果值是布爾值,如果輸出列的類型類別是數(shù)字,那么它的字符串表示方式將被認(rèn)為是1
或0
,否則
true
或 false
。)
如果一個(gè)列的XPath表達(dá)式返回一個(gè)非空的XML節(jié)點(diǎn)集,并且該列的PostgreSQL類型是xml
,那么如果該列是文檔或內(nèi)容形式的,那么該列將被精確地分配表達(dá)式結(jié)果。 [7]
分配給xml
輸出列的非XML結(jié)果會(huì)產(chǎn)生內(nèi)容,一個(gè)帶有結(jié)果字符串值的單個(gè)文本節(jié)點(diǎn)。分配給任何其他類型的列的XML結(jié)果不能有一個(gè)以上的節(jié)點(diǎn),否則會(huì)產(chǎn)生錯(cuò)誤。如果正好有一個(gè)節(jié)點(diǎn),則該列將被設(shè)置為將該節(jié)點(diǎn)的字符串值(如XPath 1.0 string
函數(shù)定義的那樣)分配給PostgreSQL類型。
一個(gè)XML元素的字符串值是字符串值的協(xié)整,按文檔的順序。該元素中包含的所有文本節(jié)點(diǎn)及其子節(jié)點(diǎn)。字符串 元素的值是一個(gè)沒有下級(jí)文本節(jié)點(diǎn)的元素的值是一個(gè) 空字符串(不是NULL
)。任何xsi:nil
屬性都會(huì)被忽略。請(qǐng)注意,兩個(gè)非文本之間的text()
節(jié)點(diǎn)只用空格,而兩個(gè)非文本 元素,并且保留了text()
上的前導(dǎo)白格。節(jié)點(diǎn)不被扁平化。XPath
1.0中的string
函數(shù)可以參考XPath 1.0中的 定義其他XML節(jié)點(diǎn)類型和非XML值的字符串值的規(guī)則。
這里介紹的轉(zhuǎn)換規(guī)則并不完全是SQL標(biāo)準(zhǔn)中的轉(zhuǎn)換規(guī)則,如第 D.3.1.3 節(jié)中討論的那樣。
如果路徑表達(dá)式為給定行返回一個(gè)空節(jié)點(diǎn)集(通常情況下,當(dāng)它不匹配時(shí)),該列將被設(shè)置為NULL
,除非指定了default_expression
;然后使用評(píng)價(jià)該表達(dá)式產(chǎn)生的值。
default_expression
,而不是在調(diào)用xmltable
時(shí)立即被評(píng)價(jià),而是在每次需要列的默認(rèn)值時(shí),都會(huì)被評(píng)價(jià)。 如果表達(dá)式符合穩(wěn)定或不可更改的條件,則可以跳過重復(fù)評(píng)價(jià)。 這意味著,你可以在default_expression
中使用像nextval
這樣的不穩(wěn)定函數(shù)。
列可能會(huì)被標(biāo)記為NOT NULL
。如果一個(gè)NOT NULL
列的column_expression
不匹配任何東西并且沒有DEFAULT
或者default_expression
也計(jì)算為空,則會(huì)報(bào)告一個(gè)錯(cuò)誤。
例子:
CREATE TABLE xmldata AS SELECT
xml $$
<ROWS>
<ROW id="1">
<COUNTRY_ID>AU</COUNTRY_ID>
<COUNTRY_NAME>Australia</COUNTRY_NAME>
</ROW>
<ROW id="5">
<COUNTRY_ID>JP</COUNTRY_ID>
<COUNTRY_NAME>Japan</COUNTRY_NAME>
<PREMIER_NAME>Shinzo Abe</PREMIER_NAME>
<SIZE unit="sq_mi">145935</SIZE>
</ROW>
<ROW id="6">
<COUNTRY_ID>SG</COUNTRY_ID>
<COUNTRY_NAME>Singapore</COUNTRY_NAME>
<SIZE unit="sq_km">697</SIZE>
</ROW>
</ROWS>
$$ AS data;
SELECT xmltable.*
FROM xmldata,
XMLTABLE('//ROWS/ROW'
PASSING data
COLUMNS id int PATH '@id',
ordinality FOR ORDINALITY,
"COUNTRY_NAME" text,
country_id text PATH 'COUNTRY_ID',
size_sq_km float PATH 'SIZE[@unit = "sq_km"]',
size_other text PATH
'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_km"]/@unit)',
premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified');
id | ordinality | COUNTRY_NAME | country_id | size_sq_km | size_other | premier_name
----+------------+--------------+------------+------------+--------------+---------------
1 | 1 | Australia | AU | | | not specified
5 | 2 | Japan | JP | | 145935 sq_mi | Shinzo Abe
6 | 3 | Singapore | SG | 697 | | not specified
接下來的例子展示了多個(gè)text()節(jié)點(diǎn)的串接、列名用作XPath過濾器的用法以及對(duì)空格、XML注釋和處理指令的處理:
CREATE TABLE xmlelements AS SELECT
xml $$
<root>
<element> Hello<!-- xyxxz -->2a2<?aaaaa?> <!--x--> bbb<x>xxx</x>CC </element>
</root>
$$ AS data;
SELECT xmltable.*
FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text);
element
-------------------------
Hello2a2 bbbxxxCC
下面的例子展示了如何使用XMLNAMESPACES
子句指定用在XML文檔以及XPath表達(dá)式中的名字空間列表:
WITH xmldata(data) AS (VALUES ('
<example xmlns="http://example.com/myns" xmlns:B="http://example.com/b">
<item foo="1" B:bar="2"/>
<item foo="3" B:bar="4"/>
<item foo="4" B:bar="5"/>
</example>'::xml)
)
SELECT xmltable.*
FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x,
'http://example.com/b' AS "B"),
'/x:example/x:item'
PASSING (SELECT data FROM xmldata)
COLUMNS foo int PATH '@foo',
bar int PATH '@B:bar');
foo | bar
-----+-----
1 | 2
3 | 4
4 | 5
(3 rows)
下面的函數(shù)將會(huì)把關(guān)系表的內(nèi)容映射成 XML 值。它們可以被看成是 XML 導(dǎo)出功能:
table_to_xml
( table
regclass
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
query_to_xml
( query
text
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
cursor_to_xml
( cursor
refcursor
, count
integer
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
table_to_xml
映射由參數(shù)table
傳遞的命名表的內(nèi)容。regclass
類型接受使用常見標(biāo)記標(biāo)識(shí)表的字符串,包括可選的模式限定和雙引號(hào)。query_to_xml
執(zhí)行由參數(shù)query
傳遞的查詢并且映射結(jié)果集。
cursor_to_xml
從cursor
指定的游標(biāo)中取出指定數(shù)量的行。如果需要映射一個(gè)大型的表,我們推薦這種變體,因?yàn)槊恳粋€(gè)函數(shù)都是在內(nèi)存中構(gòu)建結(jié)果值的。
如果tableforest
為假,則結(jié)果的 XML 文檔看起來像這樣:
<tablename>
<row>
<columnname1>data</columnname1>
<columnname2>data</columnname2>
</row>
<row> ... </row> ...
</tablename>
如果tableforest
為真,結(jié)果是一個(gè)看起來像這樣的 XML 內(nèi)容片斷:
<tablename>
<columnname1>data</columnname1>
<columnname2>data</columnname2>
</tablename>
<tablename>
...
</tablename>
...
如果沒有表名可用,在映射一個(gè)查詢或一個(gè)游標(biāo)時(shí),在第一種格式中使用串table
,在第二種格式中使用row
。
這幾種格式的選擇由用戶決定。第一種格式是一個(gè)正確的 XML 文檔,它在很多應(yīng)用中都很重要。如果結(jié)果值要被重組為一個(gè)文檔,第二種格式在cursor_to_xml
函數(shù)中更有用。前文討論的產(chǎn)生 XML 內(nèi)容的函數(shù)(特別是xmlelement
)可以被用來把結(jié)果修改成符合用戶的要求。
數(shù)據(jù)值會(huì)被以前文的函數(shù)xmlelement
中描述的相同方法映射。
參數(shù)nulls
決定空值是否會(huì)被包含在輸出中。如果為真,列中的空值被表示為:
<columnname xsi:nil="true"/>
其中xsi
是 XML 模式實(shí)例的 XML 名字空間前綴。一個(gè)合適的名字空間聲明將被加入到結(jié)果值中。如果為假,包含空值的列將被從輸出中忽略掉。
參數(shù)targetns
指定想要的結(jié)果的 XML 名字空間。如果沒有想要的特定名字空間,將會(huì)傳遞一個(gè)空串。
下面的函數(shù)返回 XML 模式文檔,這些文檔描述上述對(duì)應(yīng)函數(shù)所執(zhí)行的映射:
table_to_xmlschema
( table
regclass
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
query_to_xmlschema
( query
text
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
cursor_to_xmlschema
( cursor
refcursor
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
最重要的是相同的參數(shù)被傳遞來獲得匹配的 XML 數(shù)據(jù)映射和 XML 模式文檔。
下面的函數(shù)產(chǎn)生 XML 數(shù)據(jù)映射和對(duì)應(yīng)的 XML 模式,并把產(chǎn)生的結(jié)果鏈接在一起放在一個(gè)文檔(或森林)中。在要求自包含和自描述的結(jié)果是它們非常有用:
table_to_xml_and_xmlschema
( table
regclass
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
query_to_xml_and_xmlschema
( query
text
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
另外,下面的函數(shù)可用于產(chǎn)生相似的整個(gè)模式或整個(gè)當(dāng)前數(shù)據(jù)庫的映射:
schema_to_xml
( schema
name
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
schema_to_xmlschema
( schema
name
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
schema_to_xml_and_xmlschema
( schema
name
, nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
database_to_xml
( nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
database_to_xmlschema
( nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
database_to_xml_and_xmlschema
( nulls
boolean
,
tableforest
boolean
, targetns
text
) → xml
這些函數(shù)會(huì)忽略當(dāng)前用戶不可讀的表。數(shù)據(jù)庫范圍的函數(shù)還會(huì)忽略當(dāng)前用戶沒有USAGE
(查找)權(quán)限的模式。
請(qǐng)注意,這可能會(huì)產(chǎn)生大量數(shù)據(jù),這些數(shù)據(jù)需要在內(nèi)存中構(gòu)建。 當(dāng)請(qǐng)求大型模式或數(shù)據(jù)庫的內(nèi)容映射時(shí),可能值得考慮單獨(dú)映射表,甚至可能通過游標(biāo)。
一個(gè)模式內(nèi)容映射的結(jié)果看起來像這樣:
<schemaname>
table1-mapping
table2-mapping
...
</schemaname>
其中一個(gè)表映射的格式取決于上文解釋的tableforest
參數(shù)。
一個(gè)數(shù)據(jù)庫內(nèi)容映射的結(jié)果看起來像這樣:
<dbname>
<schema1name>
...
</schema1name>
<schema2name>
...
</schema2name>
...
</dbname>
其中的模式映射如上所述。
作為一個(gè)使用這些函數(shù)產(chǎn)生的輸出的例子,例 9.1展示了一個(gè) XSLT 樣式表,它將table_to_xml_and_xmlschema
的輸出轉(zhuǎn)換為一個(gè)包含表數(shù)據(jù)的扁平轉(zhuǎn)印的 HTML 文檔。以一種相似的方式,這些函數(shù)的結(jié)果可以被轉(zhuǎn)換成其他基于
XML 的格式。
例 9.1. 轉(zhuǎn)換 SQL/XML 輸出到 HTML 的 XSLT 樣式表
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/xhtml"
>
<xsl:output method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
indent="yes"/>
<xsl:template match="/*">
<xsl:variable name="schema" select="http://xsd:schema"/>
<xsl:variable name="tabletypename"
select="$schema/xsd:element[@name=name(current())]/@type"/>
<xsl:variable name="rowtypename"
select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/>
<html>
<head>
<title><xsl:value-of select="name(current())"/></title>
</head>
<body>
<table>
<tr>
<xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name">
<th><xsl:value-of select="."/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="row">
<tr>
<xsl:for-each select="*">
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
[7]
在頂層包含一個(gè)以上的元素節(jié)點(diǎn)的結(jié)果,或者在元素之外的非空格文本,就是內(nèi)容形式的一個(gè)例子。一個(gè)XPath結(jié)果可以是這兩種形式的,例如,如果它返回的是一個(gè)從包含它的元素中選擇的屬性節(jié)點(diǎn)。這樣的結(jié)果將被放到內(nèi)容形式中,每個(gè)不允許的節(jié)點(diǎn)都會(huì)被替換為它的字符串值,就像XPath 1.0string
函數(shù)定義的那樣。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: