支援的版本: 目前 (17) / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

9.15. XML 函數 #

本節描述的函數和類函數的運算式,是用於處理 xml 型別的值。關於 xml 型別的資訊,請參閱 第 8.13 節。用於轉換為和轉換自 xml 型別的類函數運算式 xmlparsexmlserialize 在那裡有文件說明,而不是在本節中。

要使用這些函數中的大多數,需要以 configure --with-libxml 建置 PostgreSQL

9.15.1. 產生 XML 內容 #

可以使用一組函數和類函數運算式,從 SQL 資料產生 XML 內容。因此,它們特別適合於將查詢結果格式化為 XML 文件,以便在用戶端應用程式中進行處理。

9.15.1.1. xmltext #

xmltext ( text ) → xml

函數 xmltext 傳回一個 XML 值,該值具有一個包含輸入引數作為其內容的單一文字節點。會逸出預定義的實體,例如 & 符號 (&)、左角括號和右角括號 (< >) 和引號 ("")。

範例

SELECT xmltext('< foo & bar >');
         xmltext
-------------------------
 &lt; foo &amp; bar &gt;

9.15.1.2. xmlcomment #

xmlcomment ( text ) → xml

函數 xmlcomment 建立一個 XML 值,該值包含一個 XML 註解,其中包含指定的文字作為內容。文字不能包含 -- 或以 - 結尾,否則產生的結構將不是有效的 XML 註解。如果引數為 Null,則結果為 Null。

範例

SELECT xmlcomment('hello');

  xmlcomment
--------------
 <!--hello-->

9.15.1.3. xmlconcat #

xmlconcat ( xml [, ...] ) → xml

函數 xmlconcat 會串連個別 XML 值的清單,以建立包含 XML 內容片段的單一值。會省略 Null 值;只有在沒有非 Null 引數時,結果才會是 Null。

範例

SELECT xmlconcat('<abc/>', '<bar>foo</bar>');

      xmlconcat
----------------------
 <abc/><bar>foo</bar>

XML 宣告(如果存在)會依以下方式組合。如果所有引數值都具有相同的 XML 版本宣告,則結果中使用該版本,否則不使用版本。如果所有引數值都具有獨立宣告值 yes,則結果中使用該值。如果所有引數值都具有獨立宣告值,且至少一個為 no,則結果中使用該值。否則,結果將沒有獨立宣告。如果判斷結果需要獨立宣告,但沒有版本宣告,則將使用版本為 1.0 的版本宣告,因為 XML 需要 XML 宣告才能包含版本宣告。在所有情況下,編碼宣告都會被忽略並移除。

範例

SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>');

             xmlconcat
-----------------------------------
 <?xml version="1.1"?><foo/><bar/>

9.15.1.4. xmlelement #

xmlelement ( NAME name [, XMLATTRIBUTES ( attvalue [ AS attname ] [, ...] ) ] [, content [, ...]] ) → xml

xmlelement 運算式會產生一個具有給定名稱、屬性和內容的 XML 元素。語法中顯示的 nameattname 項目是簡單的識別碼,而不是值。attvaluecontent 項目是運算式,可以產生任何 PostgreSQL 資料型別。XMLATTRIBUTES 中的引數會產生 XML 元素的屬性;content 值會串連以形成其內容。

範例

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 名稱的元素和屬性名稱會透過將違規字元替換為序列 _xHHHH_ 來逸出,其中 HHHH 是字元的 Unicode 程式碼點的十六進位標記法。例如

SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));

            xmlelement
----------------------------------
 <foo_x0024_bar a_x0026_b="xyz"/>

如果屬性值是欄位參照,則不需要指定明確的屬性名稱,在這種情況下,預設情況下欄位的名稱將用作屬性名稱。在其他情況下,必須為屬性指定明確的名稱。因此,此範例有效

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;

如果指定了元素內容,則會根據其資料型別格式化。如果內容本身是 xml 型別,則可以建構複雜的 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>

其他型別的內容將格式化為有效的 XML 字元資料。這特別表示字元 <、> 和 & 將轉換為實體。二進位資料(資料型別 bytea)將以 base64 或十六進位編碼表示,具體取決於組態參數 xmlbinary 的設定。預計個別資料型別的特定行為會發展,以便使 PostgreSQL 對應與 SQL:2006 及更高版本中指定的對應一致,如 第 D.3.1.3 節中所述。

9.15.1.5. xmlforest #

xmlforest ( content [ AS name ] [, ...] ) → xml

xmlforest 運算式會使用給定的名稱和內容產生元素的 XML 森林(序列)。與 xmlelement 一樣,每個 name 必須是一個簡單的識別碼,而 content 運算式可以具有任何資料型別。

範例

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>
 ...

如第二個範例所示,如果內容值是欄位參照,則可以省略元素名稱,在這種情況下,預設情況下會使用欄位名稱。否則,必須指定名稱。

不符合有效 XML 名稱的元素名稱會按照上面 xmlelement 的方式進行跳脫處理。同樣地,除非內容資料的類型已經是 xml,否則也會跳脫內容資料以產生有效的 XML 內容。

請注意,如果 XML 森林由多個元素組成,則它們不是有效的 XML 文件,因此將 xmlforest 運算式包裝在 xmlelement 中可能很有用。

9.15.1.6. xmlpi #

xmlpi ( NAME name [, content ] ) → xml

xmlpi 運算式會建立 XML 處理指令。如同 xmlelement 一樣,name 必須是一個簡單的識別符號,而 content 運算式可以有任何資料類型。如果 content 存在,則不得包含字元序列 ?>

範例

SELECT xmlpi(name php, 'echo "hello world";');

            xmlpi
-----------------------------
 <?php echo "hello world";?>

9.15.1.7. xmlroot #

xmlroot ( xml, VERSION {text|NO VALUE} [, STANDALONE {YES|NO|NO VALUE} ] ) → xml

xmlroot 運算式會修改 XML 值根節點的屬性。如果指定了版本,它會取代根節點版本宣告中的值;如果指定了獨立設定,它會取代根節點獨立宣告中的值。

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>

9.15.1.8. xmlagg #

xmlagg ( xml ) → xml

與此處描述的其他函式不同,函式 xmlagg 是一個彙總函式。它會將輸入值串連到彙總函式呼叫,很像 xmlconcat 的功能,除了串連發生在多個資料列上,而不是單一資料列中的多個運算式。有關彙總函式的更多資訊,請參閱第 9.21 節

範例

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/>

為了確定串連的順序,可以將 ORDER BY 子句新增到彙總呼叫中,如第 4.2.7 節中所述。例如

SELECT xmlagg(x ORDER BY y DESC) FROM test;
        xmlagg
----------------------
 <bar/><foo>abc</foo>

以前的版本建議使用以下非標準方法,但在特定情況下可能仍然有用

SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
        xmlagg
----------------------
 <bar/><foo>abc</foo>

9.15.2. XML 述詞 #

本節中描述的運算式會檢查 xml 值的屬性。

9.15.2.1. IS DOCUMENT #

xml IS DOCUMENTboolean

如果引數 XML 值是正確的 XML 文件,則 IS DOCUMENT 運算式會傳回 true;如果不是 (也就是內容片段),則傳回 false;如果引數為 null,則傳回 null。關於文件和內容片段之間的差異,請參閱第 8.13 節

9.15.2.2. IS NOT DOCUMENT #

xml IS NOT DOCUMENTboolean

如果引數 XML 值是正確的 XML 文件,則 IS NOT DOCUMENT 運算式會傳回 false;如果不是 (也就是內容片段),則傳回 true;如果引數為 null,則傳回 null。

9.15.2.3. XMLEXISTS #

XMLEXISTS ( text PASSING [BY {REF|VALUE}] xml [BY {REF|VALUE}] ) → boolean

函式 xmlexists 會評估 XPath 1.0 運算式(第一個引數),並將傳遞的 XML 值作為其上下文項目。如果評估的結果產生一個空的節點集合,則函式傳回 false;如果產生任何其他值,則傳回 true。如果任何引數為 null,則函式傳回 null。作為上下文項目傳遞的非 null 值必須是 XML 文件,而不是內容片段或任何非 XML 值。

範例

SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>');

 xmlexists
------------
 t
(1 row)

PostgreSQL 中接受 BY REFBY VALUE 子句,但會忽略它們,如第 D.3.2 節中所述。

在 SQL 標準中,xmlexists 函式會以 XML 查詢語言評估運算式,但 PostgreSQL 僅允許 XPath 1.0 運算式,如第 D.3.1 節中所述。

9.15.2.4. xml_is_well_formed #

xml_is_well_formed ( text ) → boolean
xml_is_well_formed_document ( text ) → boolean
xml_is_well_formed_content ( text ) → boolean

這些函式會檢查 text 字串是否代表格式正確的 XML,並傳回布林值結果。xml_is_well_formed_document 檢查格式正確的文件,而 xml_is_well_formed_content 檢查格式正確的內容。xml_is_well_formedxmloption 組態參數設定為 DOCUMENT 時執行前者,而在設定為 CONTENT 時執行後者。這表示 xml_is_well_formed 可用於查看簡單地轉換為 xml 類型是否會成功,而其他兩個函式則可用於查看對應的 XMLPARSE 變體是否會成功。

範例

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="https://postgresql.dev.org.tw/stuff">bar</pg:foo>');
 xml_is_well_formed_document
-----------------------------
 t
(1 row)

SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="https://postgresql.dev.org.tw/stuff">bar</my:foo>');
 xml_is_well_formed_document
-----------------------------
 f
(1 row)

最後一個範例顯示,檢查包括命名空間是否正確匹配。

9.15.3. 處理 XML #

為了處理 xml 資料類型的值,PostgreSQL 提供了 xpathxpath_exists 函式(用於評估 XPath 1.0 運算式)以及 XMLTABLE 表格函式。

9.15.3.1. xpath #

xpath ( xpath text, xml xml [, nsarray text[] ] ) → xml[]

函式 xpath 會針對 XML 值 xml 評估 XPath 1.0 運算式 xpath(以文字形式給出)。它會傳回 XML 值的陣列,該陣列對應於 XPath 運算式產生的節點集合。如果 XPath 運算式傳回純量值而不是節點集合,則會傳回單一元素陣列。

第二個引數必須是格式正確的 XML 文件。特別是,它必須具有單一的根節點元素。

函式的可選第三個引數是命名空間對應的陣列。此陣列應為二維 text 陣列,第二軸的長度等於 2(即,它應該是陣列的陣列,每個陣列恰好包含 2 個元素)。每個陣列條目的第一個元素是命名空間名稱(別名),第二個元素是命名空間 URI。此陣列中提供的別名不需要與 XML 文件本身中使用的別名相同(換句話說,在 XML 文件和 xpath 函式上下文中,別名都是本地的)。

範例

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)

要處理預設(匿名)命名空間,請執行以下操作

SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
             ARRAY[ARRAY['mydefns', 'http://example.com']]);

 xpath
--------
 {test}
(1 row)

9.15.3.2. xpath_exists #

xpath_exists ( xpath text, xml xml [, nsarray text[] ] ) → boolean

函式 xpath_existsxpath 函式的特殊形式。此函式不傳回滿足 XPath 1.0 運算式的個別 XML 值,而是傳回一個布林值,指示查詢是否滿足(具體來說,它是否產生了空節點集合以外的任何值)。此函式等效於 XMLEXISTS 述詞,但它也提供對命名空間對應引數的支援。

範例

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)

9.15.3.3. 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 運算式會根據 XML 值、用於提取資料列的 XPath 篩選器和一組欄定義來產生表格。雖然它在語法上類似於函式,但它只能作為查詢的 FROM 子句中的表格出現。

可選的 XMLNAMESPACES 子句提供一個逗號分隔的命名空間定義列表,其中每個 namespace_uri 都是一個 text 表達式,每個 namespace_name 都是一個簡單的識別符。 它指定了文件中使用的 XML 命名空間及其別名。 目前不支援預設命名空間規範。

必要的 row_expression 參數是一個 XPath 1.0 表達式(以 text 形式給出),它會被評估,並將 XML 值 document_expression 作為其上下文項目傳遞,以獲得一組 XML 節點。 這些節點就是 xmltable 轉換成輸出列的內容。 如果 document_expression 為空,或者 row_expression 產生一個空的節點集合或任何非節點集合的值,則不會產生任何列。

document_expressionrow_expression 提供上下文項目。 它必須是一個格式良好的 XML 文件;不接受片段/森林。 BY REFBY VALUE 子句被接受但被忽略,如 第 D.3.2 節中所述。

在 SQL 標準中,xmltable 函數評估 XML 查詢語言中的表達式,但 PostgreSQL 僅允許 XPath 1.0 表達式,如 第 D.3.1 節中所述。

必要的 COLUMNS 子句指定將在輸出表中產生的欄位。 有關格式,請參閱上面的語法摘要。 每個欄位都需要一個名稱,以及一個資料類型(除非指定了 FOR ORDINALITY,在這種情況下,integer 類型是隱含的)。 路徑、預設值和可空子句是可選的。

標記為 FOR ORDINALITY 的欄位將會用列號填充,從 1 開始,按照從 row_expression 的結果節點集合中檢索節點的順序排列。 最多只能有一個欄位標記為 FOR ORDINALITY

注意

XPath 1.0 沒有指定節點集合中節點的順序,因此依賴於特定結果順序的程式碼將取決於實作。 詳細資訊可以在 第 D.3.1.2 節中找到。

欄位的 column_expression 是一個 XPath 1.0 表達式,它針對每一列進行評估,並將來自 row_expression 結果的當前節點作為其上下文項目,以找到欄位的值。 如果沒有給出 column_expression,則欄位名稱將用作隱含路徑。

如果欄位的 XPath 表達式傳回一個非 XML 值(在 XPath 1.0 中僅限於字串、布林值或雙精度浮點數),並且欄位具有 xml 以外的 PostgreSQL 類型,則該欄位將被設定,就像將該值的字串表示形式指派給 PostgreSQL 類型一樣。 (如果該值是一個布林值,如果輸出欄位的類型類別是數值,則其字串表示形式將被視為 10,否則將被視為 truefalse。)

如果欄位的 XPath 表達式傳回一個非空的 XML 節點集合,並且該欄位的 PostgreSQL 類型為 xml,則如果該表達式是文件或內容形式,則該欄位將被完全指派該表達式結果。 [8]

指派給 xml 輸出欄位的非 XML 結果會產生內容,也就是具有結果字串值的單個文字節點。 指派給任何其他類型欄位的 XML 結果可能沒有多個節點,否則會引發錯誤。 如果只有一個節點,則該欄位將被設定,就像將該節點的字串值(如 XPath 1.0 string 函數所定義)指派給 PostgreSQL 類型一樣。

XML 元素的字串值是該元素及其後代中包含的所有文字節點的串聯,按照文件順序排列。 沒有後代文字節點的元素的字串值為空字串(不是 NULL)。 任何 xsi:nil 屬性都會被忽略。 請注意,兩個非文字元素之間的僅包含空白字元的 text() 節點會被保留,並且 text() 節點上的前導空白字元不會被扁平化。 可以查詢 XPath 1.0 string 函數,以瞭解定義其他 XML 節點類型和非 XML 值的字串值的規則。

此處提供的轉換規則與 SQL 標準的規則並不完全相同,如 第 D.3.1.3 節中所述。

如果路徑表達式對於給定的列傳回一個空的節點集合(通常,當它不匹配時),則該欄位將被設定為 NULL,除非指定了 default_expression;然後將使用評估該表達式所產生的值。

並非在呼叫 xmltable 時立即評估 default_expression,而是在每次需要欄位的預設值時才評估它。 如果該表達式符合 stable 或 immutable 的條件,則可以跳過重複評估。 這表示您可以在 default_expression 中有效地使用 volatile 函數,例如 nextval

欄位可以標記為 NOT NULL。 如果 NOT NULL 欄位的 column_expression 不匹配任何內容,並且沒有 DEFAULTdefault_expression 也評估為 null,則會報告錯誤。

範例

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

以下範例顯示了多個 text() 節點的串聯,使用欄位名稱作為 XPath 篩選器,以及對待空白字元、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 表達式中使用的一系列命名空間

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)

9.15.4. 將表對應到 XML #

以下函數將關係表的內容對應到 XML 值。 它們可以被視為 XML 匯出功能

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 函式會將指定資料表的內容對應到 XML,資料表名稱會當作參數 table 傳入。regclass 型別接受字串,字串使用常見的表示法識別資料表,包含選擇性的綱要名稱和雙引號(詳情請參閱 第 8.19 節)。query_to_xml 函式會執行其文字當作參數 query 傳入的查詢,並對應結果集。cursor_to_xml 函式會從參數 cursor 指定的游標中提取指定數量的列。如果必須對應大型資料表,建議使用此變體,因為每個函式都會在記憶體中建立結果值。

如果 tableforest 為 false,則產生的 XML 文件看起來會像這樣:

<tablename>
  <row>
    <columnname1>data</columnname1>
    <columnname2>data</columnname2>
  </row>

  <row>
    ...
  </row>

  ...
</tablename>

如果 tableforest 為 true,則結果會是看起來像這樣的 XML 內容片段:

<tablename>
  <columnname1>data</columnname1>
  <columnname2>data</columnname2>
</tablename>

<tablename>
  ...
</tablename>

...

如果沒有資料表名稱可用(也就是說,當對應查詢或游標時),第一個格式會使用字串 table,第二個格式會使用 row

這些格式的選擇由使用者決定。第一種格式是正確的 XML 文件,這在許多應用程式中很重要。如果結果值稍後要重新組合成一個文件,則第二種格式在 cursor_to_xml 函式中往往更有用。上面討論的用於產生 XML 內容的函式,特別是 xmlelement,可用於根據喜好修改結果。

資料值的對應方式與上面針對 xmlelement 函式描述的方式相同。

參數 nulls 決定是否應在輸出中包含 Null 值。如果為 true,則欄位中的 Null 值會表示為:

<columnname xsi:nil="true"/>

其中 xsi 是 XML Schema Instance 的 XML 命名空間前置詞。適當的命名空間宣告將會新增到結果值。如果為 false,則包含 Null 值的欄位將會從輸出中省略。

參數 targetns 指定結果所需的 XML 命名空間。如果不需要特定的命名空間,則應傳遞空字串。

以下函式會傳回 XML Schema 文件,描述對應函式執行的對應:

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

為了取得匹配的 XML 資料對應和 XML Schema 文件,務必傳入相同的參數。

以下函式會在一個文件(或叢集)中產生 XML 資料對應和對應的 XML Schema,並將它們連結在一起。如果需要獨立且自我描述的結果,它們會很有用:

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

此外,以下函式可用於產生整個綱要或整個目前資料庫的類似對應:

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

這些函式會忽略目前使用者無法讀取的資料表。資料庫範圍的函式還會忽略目前使用者沒有 USAGE(查詢)權限的綱要。

請注意,這些函式可能會產生大量資料,需要在記憶體中建立。當請求大型綱要或資料庫的內容對應時,考慮改為分別對應資料表可能值得,甚至可以透過游標來進行。

綱要內容對應的結果看起來像這樣:

<schemaname>

table1-mapping

table2-mapping

...

</schemaname>

其中資料表對應的格式取決於 tableforest 參數,如上所述。

資料庫內容對應的結果看起來像這樣:

<dbname>

<schema1name>
  ...
</schema1name>

<schema2name>
  ...
</schema2name>

...

</dbname>

其中綱要對應如上所述。

作為使用這些函式產生的輸出的範例,範例 9.1 顯示了一個 XSLT 樣式表,它將 table_to_xml_and_xmlschema 的輸出轉換為包含資料表資料的表格呈現的 HTML 文件。以類似的方式,這些函式的結果可以轉換為其他基於 XML 的格式。

範例 9.1. 用於將 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="//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>



[8] 在最上層包含多個元素節點,或者元素外包含非空白文字的結果是內容形式的一個範例。 XPath 結果可能不是任何一種形式,例如,如果它傳回從包含它的元素中選取的屬性節點。 這種結果將被放入內容形式,每個這種不允許的節點都被其字串值替換,如 XPath 1.0 string 函數的定義。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步說明的地方,請使用此表單來報告文件問題。