★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

9.15. XML関数 #

この節で説明される関数および擬似関数式は、xml型の値に対して機能します。 xml型についての情報は8.13を参照してください。 xml型のやりとりを変換するxmlparseおよびxmlserialize擬似関数式はこの節ではなく、そこに記載されています。

これらの関数の大半はPostgreSQLconfigure --with-libxmlでビルドされていることを必要としています。

9.15.1. XML内容の生成 #

SQLデータからXML内容を生成するために関数と擬似関数式の一式が提供されています。 そのようなものとして、クライアントアプリケーションが問い合わせ結果を処理のためXML文書に書式化するのにこれらは特に適しています。

9.15.1.1. xmlcomment #

xmlcomment ( text ) → xml

関数xmlcommentは指定のテキストを内容とするXMLコメントを含んだXML値を作成します。 テキストは--を含むこと、または-で終結することはできません。さもないと結果として構築されるXMLコメントは有効になりません。 引数がNULLならば結果もNULLになります。

例:

SELECT xmlcomment('hello');

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

9.15.1.2. xmlconcat #

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

関数xmlconcatは、個々のXML値のリストを結合し、XMLの内容断片を含む単一の値を作成します。 NULL値は削除され、NULL以外の引数が存在しないときのみ結果はNULLになります。

例:

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

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

XML宣言が提示されている場合は次のように組み合わされます。 全ての引数の値が同一のXML version宣言を持っていれば、そのversionが結果に使用されます。さもなければversionは使用されません。 全ての引数の値でstandaloneの宣言値がyesであれば、その値が結果に使用されます。 全ての引数の値にstandalone宣言値があり、その中で1つでもnoがある場合、それが結果に使用されます。 それ以外の場合は、結果はstandalone宣言を持ちません。 standalone宣言を必要とするが、standalone宣言がないという結果になった場合には、version 1.0のversion宣言が使用されます。 これはXMLがXML宣言においてversion宣言を含むことを要求するためです。 encoding宣言は無視され、全ての場合で削除されます。

例:

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

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

9.15.1.3. 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は16進数によるその文字の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)は、設定パラメータxmlbinaryの設定にしたがって、base64もしくは16進符号化方式で表現されます。 個々のデータ型に対する特定の動作は、D.3.1.3で説明されているように、SQL:2006以降で指定された型をPostgreSQLデータ型に調整するため発展すると期待されます。

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

第2の例に見られるように、内容の値が列参照の場合、要素名は省略可能です。この時は、列名がデフォルトで使用されます。 そうでない時は、名前が指定されなければなりません。

有効なXML名ではない要素名は上のxmlelementで説明した通りエスケープされます。 同様にして、既にxml型であるものを除き、内容データは有効なXML内容になるようにエスケープされます。

XMLフォレストは2つ以上の要素からなる場合、有効なXML文書ではないことに注意してください。 したがって、xmlelement内にxmlforest式をラップすることが有用なことがあります。

9.15.1.5. 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.6. xmlroot #

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

xmlroot式はXML値のルートノードの属性を変更します。 versionが指定されていると、ルートノードのversion宣言での値を変更し、standalone設定が指定されていると、ルートノードのstandalone宣言での値を変更します。

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

連結の順序を決定するため、4.2.7に記述されているようにORDER BY句を集計呼び出しに追加することができます。 以下は例です。

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

IS DOCUMENTは引数XML値が適切なXML文書であれば真を返し、そうでなければ(つまり、内容の断片)偽を返すか、もしくは引数がNULLであればNULLを返します。 文書と内容の断片の差異については8.13を参照してください。

9.15.2.2. IS NOT DOCUMENT #

xml IS NOT DOCUMENTboolean

IS NOT DOCUMENTは引数XML値が適切なXML文書であれば偽を返し、そうでなければ(つまり、内容の断片)真を返すか、もしくは引数がNULLであればNULLを返します。

9.15.2.3. XMLEXISTS #

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

関数xmlexistsは渡されたXML値をコンテキスト項目としてXPath 1.0式(第一引数)を評価します。 この関数は評価が空のノード集合を生成する場合には偽を返し、それ以外の値を返すならば真を返します。 もしどれかの引数が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)

PostgreSQLBY REF句とBY VALUE句を受け付けますが、D.3.2で説明されているように無視します。

SQL標準ではxmlexists関数はXML問い合わせ言語における式を評価しますが、D.3.1で説明されているように、PostgreSQLはXPath 1.0の式だけを受け付けます。

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_is_well_formed_documentは文書が整形式かをチェックし、一方xml_is_well_formed_contentは内容が整形式かをチェックします。 xml_is_well_formedは、xmloptionパラメータ値がDOCUMENTに設定されていれば前者を、CONTENTが設定されていれば後者のチェックを実施します。 これは、xml_is_well_formedは単純なxml型へのキャストが成功するかの判断に有用であり、その他の2つの関数は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="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)

最後の例は、名前空間が正しく一致しているかのチェックも含むことを示しています。

9.15.3. XMLの処理 #

データ型xmlの値を処理するため、PostgreSQLはXPath 1.0式を評価する関数xpathおよびxpath_existsと、テーブル関数XMLTABLEを提供しています。

9.15.3.1. xpath #

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

関数xpathは、XML値xmlに対し、XPath 1.0式xpath(テキストとして指定)を評価します。 そして、XPath式で作成されたノード集合に対応するXML値の配列を返します。 もし、XPath式がノード集合ではなくスカラー値を返す場合、単一要素の配列が返されます。

2番目の引数は整形済XML文書でなければなりません。特に、単一のルートノード要素を持たなければなりません。

オプショナルな関数の3番目の引数は名前空間マッピング配列です。 この配列は、第2軸が2に等しい長さをもつ2次元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_existsは、xpath関数の特別な形式です。 この関数は、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_uritext式で、namespace_nameは単純な識別子です。 これは文書とその別名で使用されるXML名前空間を指定します。 デフォルトの名前空間指定は現在のところサポートされていません。

必須のrow_expression引数は評価されるXPath 1.0式(textで与えます)で、XMLノード集合を得るためにdocument_expressionをそのコンテキスト項目として渡します。 このノードはxmltableが出力行に変換します。 document_expressionがNULLであるか、row_expressionが空のノード集合あるいはノード集合以外の値を生成するなら行は出力されません。

document_expressionrow_expressionのためのコンテキスト項目を提供します。 それは整形式XMLの文書でなければならず、フラグメントやフォレストは受け付けられません。 D.3.2で説明されているように、BY REF句とBY VALUE句は受け付けられますが、無視されます。

SQL標準ではxmltable関数はXML問い合わせ言語の式を評価しますが、D.3.1で説明されているようにPostgreSQLではXPath 1.0式だけを受け付けます。

必須のCOLUMNS句は、出力テーブルに現れる列を指定します。 形式については上記の構文サマリを参照してください。 各列には名前が必須で、データ型についても同様です。(FOR ORDINALITYが指定された場合を除きます。その場合は暗黙的にintegerが想定されます。) パス、デフォルト値、NULLを許すかどうかの句は省略できます。

FOR ORDINALITYと印がつけられた列には、row_expressionの結果ノード集合から取得されたノードの順序に対応する1から始まる行番号が入ります。 FOR ORDINALITYの印が付けられるのは最大でも1列です。

注記

XPath 1.0はノード集合内のノードの順序を指定しません。ですから、結果が特定の順序になっていることに依存するコードは実装依存となります。 詳細はD.3.1.2をご覧ください。

列のcolumn_expressionはXPath 1.0式で、row_expressionの結果における現在のノードをそのコンテキスト項目としてrow_expressionの結果に対応する各行について評価されて、列の値を得ます。 column_expression が与えられなかった場合は、暗黙的なパスとして列名が使用されます。

列のXPath式が非XML値(XPath 1.0における文字列、論理値、倍精度浮動小数点数に限られます)を返し、その列がxml以外のPostgreSQL型なら、あたかも値の文字列表現をPostgreSQL型にアサインしたように列に値がセットされます。 (値が論理値の場合、出力列型が数値カテゴリに属するならその文字列表現は1または0になり、それ外ならtrueまたはfalseになります。)

列のXPath表現が空ではないXMLノードの集合を返し、列のPostgreSQL型がxmlである場合には、式が文書あるいはフォームの内容なら、列には正確に式の結果がアサインされます。 [8]

xml出力列にアサインされた非XMLの結果は、結果の値が文字列値となる単一のテキストノードであるコンテントを生成します。 それ以外の型の列にアサインされたXMLの結果は複数のノードを持たないかも知れませんし、エラーを生じするかも知れません。 正確に一つのノードだけが存在するなら、列にはあたかもノードの文字列値(XPath 1.0 string関数の定義されているように) がPostgreSQL型にアサインされたように設定されます。

ある要素と、その子孫に含まれるすべてのテキストノードをドキュメントの順に結合したものがXML要素の文字列値です。 テキストノードの子孫を持たない要素の文字列値は空文字列です。( NULLではありません。) すべてのxsi:nil属性は無視されます。 非テキスト要素の間にある空白のみからなるtext()2つのノードは保存され、text()の先頭の空白は平坦化されないことに注意してください。 XPath 1.0 string関数が、他のXMLノード型と非XML値の文字列値を定義するルールのために参照されるかも知れません。

ここで示した変換ルールは、D.3.1.3で説明されているように、正確にSQL標準に従っているわけではありません。

パス式がある行に対して空のノード集合(典型的にはマッチしなかった場合)を返した時は、default_expressionが指定されている場合を除き、列にはNULLが設定されます。 そしてその式を評価した結果から生じる値が使用されます。

xmltableが呼び出されて直ちに評価されるのと異なり、default_expressionはその列に対してデフォルトが必要になるたびに評価されます。 式が安定(stable)または不変(immutable)とみなされる場合、評価は繰り返し行われないかもしれません。 これはdefault_expressionの中でnextvalのような揮発性関数を使用できることを意味します。

列にはNOT NULLの印をつけることができます。 NOT NULLの列のcolumn_expressionが何にもマッチせず、DEFAULTがない、あるいはdefault_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は、パラメータtableとして渡された名前付きのテーブルの内容をマップします。 regclass型はオプションのスキーマ修飾と二重引用符を含む、通常の表記法を使用しテーブルを特定する文字列を受け付けます。(詳細は8.19を参照してください。) query_to_xmlは、パラメータqueryとしてテキストが渡された問い合わせを実行し、結果セットをマップします。 cursor_to_xmlは、パラメータcursorで指定されたカーソルから提示された行数を取得します。 それぞれの関数により結果値がメモリに構築されるため、この異形は巨大なテーブルをマップする必要がある場合推奨されます。

tableforestが偽であれば、結果のXML文書は以下のようになります。

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

  <row>
    ...
  </row>

  ...
</tablename>

tableforestが真であれば、結果は以下のようなXML文書の断片です。

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

<tablename>
  ...
</tablename>

...

テーブル名が利用できないとき、つまり、問い合わせ、またはカーソルをマップする時は、最初の書式では文字列tableが使用され、2番目の書式ではrowが使用されます。

これらどの書式を選択するのかはユーザ次第です。 最初の書式は適切なXML文書で、多くのアプリケーションにおいて重要です。 第2の書式は、後に結果値が1つの文書に再び組み立てられる場合、cursor_to_xml関数内でより有用になる傾向があります。 上記で説明したXML内容を作成する関数、特にxmlelementは結果を好みにかえるために使用することができます。

データの値は上記関数xmlelementで説明したのと同じ方法でマップされます。

パラメータnullsは出力にNULL値が含まれる必要があるかを決定します。 もし真であれば列内のNULL値は以下のように表現されます。

<columnname xsi:nil="true"/>

ここでxsiはXMLスキーマインスタンスに対するXML名前空間接頭辞です。 適切な名前空間宣言が結果値に追加されます。 もし偽の場合、NULL値を含む列は単に出力から削除されます。

パラメータtargetnsは結果の希望するXML名前空間を指定します。 特定の名前空間が必要なければ、空文字列を渡す必要があります。

以下の関数は、対応する上記関数により行われたマッピングを記述するXMLスキーマ文書を返します。

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スキーマ文書を取得するため、同じパラメータが渡されることが不可欠です。

以下の関数は、XMLデータマッピングとそれに対応するXMLスキーマがお互いにリンクされた、1つの文書(またはフォレスト)を作成します。 これらは自己完結した、自己記述的な結果を希望する場合に便利です。

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>

ここで、スキーママッピングは上記のとおりです。

これらの関数で作成された出力を使用する1つの例として、例 9.1は、テーブルデータの表形式への翻訳を含むtable_to_xml_and_xmlschemaからHTML文書への出力の変換をおこなうXSLTスタイルシートを示します。 同じようにして、これらの関数の結果は他の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関数で定義されているように、そうした結果は、許可されないノードを文字列値で置き換えたコンテントフォームに設定されます。