★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

F.46. xml2

xml2モジュールはXPath問い合わせとXSLT機能を提供します。

F.46.1. 廃止予定の可能性についてのお知らせ

PostgreSQL 8.3から、SQL/XML標準に基づくXML関連の機能はコアサーバ内に存在します。 その機能は、XML構文検査、XPath問い合わせなど本モジュールが行なうことと同等のこととそれ以上のことを範囲としますが、APIには互換性はありません。 新しい標準APIのため、本モジュールは今後のバージョンのPostgreSQLで削除される予定ですので、アプリケーションの変換が推奨されています。 本モジュールの機能に新しいAPIに適用できないものがあることが分かった場合、その不足に取り組むことができるようににその問題を表明してください。

F.46.2. 関数の説明

表 F.35に本モジュールで提供する関数を示します。 これらの関数は簡単なXML解析とXPath問い合わせを提供します。 すべての引数はtext型です。 簡潔にするため説明しません。

表F.35 関数

関数結果説明
xml_valid(document) bool

これはパラメータとして与えられた文書テキストを解析し、文書が整形式のXMLであれば真を返します。 (注意:これは標準のPostgreSQL関数xml_is_well_formed()の別名です。 XMLでは整形と検証が異なる意味を持つため、xml_valid()と言う名前は技術的には正しくありません。)

xpath_string(document, query) text

これらの関数は与えられた文書に対するXPath問い合わせを評価し、結果を指定した型にキャストします。

xpath_number(document, query) float4
xpath_bool(document, query) bool
xpath_nodeset(document, query, toptag, itemtag) text

これは文書に対する問い合わせを評価し、XMLタグ内に結果を包みます。 結果が複数の値であれば、出力は以下のようになります。

<toptag>
<itemtag>Value 1 which could be an XML fragment</itemtag>
<itemtag>Value 2....</itemtag>
</toptag>

toptagまたはitemtagが空文字だった場合、対応するタグは省略されます。

xpath_nodeset(document, query) text

xpath_nodeset(document, query, toptag, itemtag)と同様ですが、結果は両方のタグを省きます。

xpath_nodeset(document, query, itemtag) text

xpath_nodeset(document, query, toptag, itemtag)と同様ですが、結果はtoptagを省きます。

xpath_list(document, query, separator) text

この関数は複数の値を指定した区切り文字で区切って返します。 例えば、区切り文字が,ならばValue 1,Value 2,Value 3となります。

xpath_list(document, query) text これは、,を区切り文字として使用する、上の関数のラッパです。

F.46.3. xpath_table

xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record

xpath_tableは各文書集合に対するXPath問い合わせ集合を評価し、結果をテーブルとして返すテーブル関数です。 元文書テーブルの主キーフィールドが結果の第一列として返されますので、結果セットを容易に結合で使用することができます。 パラメータについては表 F.36で説明します。

表F.36 xpath_tableのパラメータ

パラメータ説明
key

keyフィールドの名前です。 これは、出力テーブルの第一列として使用される単なるフィールドです。 つまり、これは各出力行の出現元を識別するレコードです。 (後述の複数値に関する注記を参照してください。)

document

XML文書を含むフィールドの名前です。

relation

文書を含むテーブルまたはビューの名前です。

xpaths

|で区切られた、1つ以上のXPath式です。

criteria

WHERE句の内容です。 これは省略することができません。 リレーション内の全行を処理したい場合はtrueまたは1=1を使用してください。


(XPath文字列を除く)これらのパラメータは普通のSQL SELECT 文に単純に置換されます。 このため、多少の柔軟性があります。

SELECT <key>, <document> FROM <relation> WHERE <criteria>

文は上の通りですので、これらのパラメータにはそれぞれの場所で有効なものであれば何でもよいわけです。 このSELECTの結果は正確に2つの列を返さなければなりません(キーまたは文書に対して複数のフィールドを列挙させようとしない限りです)。 この簡略された手法では、SQLインジェクション攻撃を防ぐためにユーザから与えられた値をすべて検証しなければならないことに注意してください。

この関数は、出力列を指定するためのAS句を付けたFROM式内で使用されなければなりません。 以下に例を示します。

SELECT * FROM
xpath_table('article_id',
            'article_xml',
            'articles',
            '/article/author|/article/pages|/article/title',
            'date_entered > ''2003-01-01'' ')
AS t(article_id integer, author text, page_count integer, title text);

このAS句は、出力テーブルの列名とその型を定義します。 先頭がkeyフィールド、残りがXPath問い合わせに対応します。 結果列より多くのXPath問い合わせが存在する場合、余った問い合わせは無視されます。 XPath問い合わせより多くの結果列が存在する場合は余った列はNULLになります。

この例でpage_count結果列が整数として定義されていることに注意してください。 関数は内部的に文字列表現で扱います。 このため、出力内で整数で扱いたいと言っている時、XPath結果の文字列表現を取り出し、整数(またはAS句で要求した任意の型)に変換するためにPostgreSQLの入力関数を使用します。 例えば結果が空など、変換できない場合はエラーになります。 ですので、データに何らかの問題があると考えられる場合、列型としてtextに限定する方がよいかもしれません。

SELECT文の呼び出しでは、単なるSELECT *でなければならない必要性はありません。 出力列を名前で参照することも他のテーブルと結合することも可能です。 この関数は希望の何らかの操作(例えば集約、結合、ソートなど)を行うことができる仮想テーブルを生成します。 このため以下をより複雑な例として示すことができます。

SELECT t.title, p.fullname, p.email
FROM xpath_table('article_id', 'article_xml', 'articles',
                 '/article/title|/article/author/@id',
                 'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ')
       AS t(article_id integer, title text, author_id integer),
     tblPeopleInfo AS p
WHERE t.author_id = p.person_id;

当然ながら、簡便にするためにこれをすべてビューとして包み隠すことができます。

F.46.3.1. 複数値の結果

xpath_table関数は各XPath問い合わせの結果が複数の値を持つ可能性があることを前提としています。 このため、この関数が返す行数は入力文書の数と同じにならない可能性があります。 返される最初の行には各問い合わせの最初の結果が、2番目の行には各問い合わせの2番目の結果が含まれます。 問い合わせの1つが他よりも少ない値を持つ場合は代わりにNULL値が返されます。

指定したXPath問い合わせが単一の結果(おそらく一意な文書識別子)のみを返すことがユーザが分かっている場合があります。 もしこれを複数の結果を返すXPathと一緒に使用されると、単一値の結果は結果の最初の行にのみ現れます。 この解決方法はより単純なXPath問い合わせに対する結合部分としてキーフィールドを使用することです。 以下に例を示します。

CREATE TABLE test (
    id int PRIMARY KEY,
    xml text
);

INSERT INTO test VALUES (1, '<doc num="C1">
<line num="L1"><a>1</a><b>2</b><c>3</c></line>
<line num="L2"><a>11</a><b>22</b><c>33</c></line>
</doc>');

INSERT INTO test VALUES (2, '<doc num="C2">
<line num="L1"><a>111</a><b>222</b><c>333</c></line>
<line num="L2"><a>111</a><b>222</b><c>333</c></line>
</doc>');

SELECT * FROM
  xpath_table('id','xml','test',
              '/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
              'true')
  AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int)
WHERE id = 1 ORDER BY doc_num, line_num

 id | doc_num | line_num | val1 | val2 | val3
----+---------+----------+------+------+------
  1 | C1      | L1       |    1 |    2 |    3
  1 |         | L2       |   11 |   22 |   33

各行にdoc_numを付けるためには、2つのxpath_tableを呼び出し、その結果を結合することです。

SELECT t.*,i.doc_num FROM
  xpath_table('id', 'xml', 'test',
              '/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
              'true')
    AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int),
  xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
    AS i(id int, doc_num varchar(10))
WHERE i.id=t.id AND i.id=1
ORDER BY doc_num, line_num;

 id | line_num | val1 | val2 | val3 | doc_num
----+----------+------+------+------+---------
  1 | L1       |    1 |    2 |    3 | C1
  1 | L2       |   11 |   22 |   33 | C1
(2 rows)

F.46.4. XSLT関数

libxsltがインストールされている場合、以下の関数を使用することができます。

F.46.4.1. xslt_process

xslt_process(text document, text stylesheet, text paramlist) returns text

この関数はXSLスタイルシートを文書に適用し、変換した結果を返します。 paramlistは、'a=1,b=2'という形で指定された、変換で使用されるパラメータ代入式のリストです。 パラメータ解析はあまり熟考されたものではないことに注意してください。パラメータ値にカンマを入れることができません。

また、変換用のパラメータを渡さない、2つのパラメータを取るバージョンのxslt_processも存在します。

F.46.5. 作者

John Gray

本モジュールの開発はTorchbox Ltd. (www.torchbox.com)が後援しました。 PostgreSQLと同じBSDライセンスです。