xml2

PostgreSQL 9.0.0文書
前のページ | 巻戻し | 付録 F. 追加で提供されるモジュール | 早送り | 次のページ

# F.42. xml2

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

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

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

## F.42.2. 関数の説明

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

表 F-31. 関数

関数 | 結果 | 説明
--- | --- | ---
`xml_is_well_formed(document)` | `bool` | これはパラメータとして与えられた文書テキストを解析し、文書が整形式のXMLであれば真を返します。 （注意:PostgreSQL 8.2以前ではこの関数は`xml_valid()`と呼ばれていました。 XMLでは整形と検証が異なる意味を持つため間違った名前でした。 古い名前もまだ利用できますが、廃止予定です。）
`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.42.3. `xpath_table`

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

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

表 F-32. `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.42.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.42.4. XSLT関数

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

### F.42.4.1. `xslt_process`

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

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

また、文書またはスタイルシートのいずれかの値が<で始まらなければ、URLとして扱われ、libxsltはそれを取り込みます。 この結果`xslt_process`をURLの内容を取り込むための道具として使用できることになります。 これにはセキュリティ上の暗示があることに注意しなければなりません。

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

## F.42.5. 作者

John Gray `<jgray@azuli.co.uk>`

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

前のページ | ホーム | 次のページ
vacuumlo | 上に戻る | 外部プロジェクト