★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

8.13. XML

xmlデータ型を使用して、XMLデータを格納することができます。 text型のフィールドにXMLデータを格納する方法より、入力された値が整形式かどうかを検査する利点があります。 また、型を安全に操作するサポート関数があります。 9.14. XML関数を参照してください。 このデータ型を使用するためには、インストレーションがconfigure --with-libxmlで構築されていることが必要です。

xml型は、XML標準で定義された整形式の文書およびXML標準によるXMLDecl? content生成規則で定義されたコンテンツフラグメントを格納することができます。 大雑把に言うと、これは、コンテンツフラグメントが2つ以上の最上位要素や文字ノードを持つことができることを意味します。 xmlvalue IS DOCUMENTという式を使用して、特定のxml値が完全な文書か単なるコンテンツフラグメントか評価することができます。

8.13.1. XML値の作成

文字データからxml型の値を生成するためには、xmlparse関数を使用してください。

XMLPARSE ( { DOCUMENT | CONTENT } value)

例:

XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')

標準SQLに従って文字列をXML値に変換するためにはこの方法しかありませんが、次のようなPostgreSQL固有の構文も使用することができます。

xml '<foo>bar</foo>'
'<foo>bar</foo>'::xml

xml型では文書型定義(DTD)に対して入力値を検証することは、入力値がDTDを指定していたとしても、行いません。 また同様に、現時点ではXML Schemaなどの他のXMLスキーマ言語に対する検証サポートも組み込まれていません。

xmlから文字列値を生成するという逆演算ではxmlserialize関数を使用してください。

XMLSERIALIZE ( { DOCUMENT | CONTENT } value AS type )

ここで、typeは、charactercharacter varyingtext(またはこれらの別名)を取ることができます。 この場合も、標準SQLに従ってxmlと文字列型間の変換を行うためにはこの方法しかありません。 PostgreSQLでは単に値をキャストすることが可能です。

XMLPARSEXMLSERIALIZEを使わずに文字列値とxmlとの間をキャストした場合、DOCUMENTCONTENTかという選択がXML optionセッション設定パラメータによって決定されます。 このパラメータは標準コマンド

SET XML OPTION { DOCUMENT | CONTENT };

または、よりPostgreSQLらしい構文

SET xmloption TO { DOCUMENT | CONTENT };

を使用して設定することができます。 デフォルトはCONTENTですので、すべての書式のXMLデータを扱うことができます。

注記

デフォルトのXMLオプション設定では、文書型宣言を含む文字列をxmlに直接キャストすることはできません。 XMLコンテンツフラグメントの定義が受け付けないためです。 この操作を行う必要がある場合、XMLPARSEを使用するかXMLオプションを変更してください。

8.13.2. 符号化方式の取扱い

クライアント側、サーバ側、および、これらを経由してやり取りされるXMLデータ内部で複数の文字符号化方式を扱う場合には注意が必要です。 テキストモードを使用してサーバに問い合わせを渡し、そしてクライアントに問い合わせ結果を渡す場合(これが通常のモードです)、PostgreSQLは、クライアントからサーバ、サーバからクライアントでやり取りされるすべての文字データを受信側の文字符号化方式に変換します。 23.3. 文字セットサポートを参照してください。 これには上の例のようなXML値の文字列表現も含まれます。 これは通常、埋め込まれたencoding宣言は変更されずに、クライアント/サーバ間でやり取りされる間に文字データが他方の符号化方式に変換されてしまうので、XMLデータ内のencodingが無効になる可能性があることを意味します。 この動作に対処するため、xml型の入力として表現された文字列に含まれているencoding宣言は無視され、その内容は常にサーバの現在の符号化方式になっているものと仮定されます。 したがって、正しく処理するためには、XMLデータにおける文字列をクライアントの現在の符号化方式で送信しなければなりません。 サーバに送信する前に文書を現在のクライアントの符号化方式に変換するか、クライアントの符号化方式を適切に調節するかは、クライアントの責任です。 出力ではxml型の値はencoding宣言を持ちません。 クライアントはすべてのデータが現在のクライアントの符号化方式であることを前提としなければなりません。

バイナリモードを使用して、問い合わせパラメータをサーバに渡し、そして問い合わせ結果をクライアントに返す場合、符号化方式の変換は行われません。 このため状況は異なります。 この場合、XMLデータ内のencoding宣言が認識され、もし存在しなければ、データがUTF-8であると仮定されます。 (XML標準の要求通りです。 PostgreSQLはUTF-16をサポートしていないことに注意してください。) 出力では、データはクライアントの符号化方式を指定したencoding宣言を持ちます。 ただし、もしクライアントの符号化方式がUTF-8の場合はencoding宣言は省略されます。

言うまでもありませんが、PostgreSQLを使用したXML処理では、XMLデータの符号化方式、クライアントの符号化方式、サーバの符号化方式が同じ場合にエラーが起こりづらく、より効率的です。 XMLデータは内部的にUTF-8として処理されますので、サーバの符号化方式が同一のUTF-8である場合、最も効率が上がります。

注意

サーバ符号化方式がUTF-8でない場合、いくつかのXMLに関係した関数は非ASCIIデータに対して全く機能しないことがあります。 特にxpath()に対する問題として知られています。

8.13.3. XML値へのアクセス

xmlデータ型は、比較演算子をまったく提供しないというところが他と異なります。 これは、XMLデータに対し、よく定義され、誰にとっても有用な比較アルゴリズムが存在しないためです。 この結果、xml列を検索値と比べて行を取り出すことはできません。 したがって通常XML値には、IDなどの別のキーフィールドを一般的に付属させなければなりません。 XML値の比較を行うもうひとつの方法は、文字列に一度変換することです。 しかし、文字列比較は有用なXML比較方法といえないことに注意してください。

xmlデータ型用の比較演算子がありませんので、この型の列に直接インデックスを作成することはできません。 XMLデータを高速に検索することが望まれるなら、その表現を文字列型にキャストし、それをインデックス付けするか、または、XPath式をインデックス付けするかという対策をとることができます。 当然ながら、インデックス付けされた式で検索されるよう実際の問い合わせを調整する必要があります。

PostgreSQLのテキスト検索機能を使用して、XMLデータの全文検索速度をあげることもできます。 しかし、PostgreSQL配布物では必要な前処理を未だサポートしていません。