xml
データ型を使用して、XMLデータを格納することができます。
text
型のフィールドにXMLデータを格納する方法より、入力された値が整形式かどうかを検査する利点があります。
また、型を安全に操作するサポート関数があります。
9.14. XML関数を参照してください。
このデータ型を使用するためには、インストレーションがconfigure --with-libxml
で構築されていることが必要です。
xml
型は、XML標準で定義された整形式の「文書」およびXML標準によるXMLDecl? content
生成規則で定義された「コンテンツ」フラグメントを格納することができます。
大雑把に言うと、これは、コンテンツフラグメントが2つ以上の最上位要素や文字ノードを持つことができることを意味します。
という式を使用して、特定のxmlvalue
IS DOCUMENTxml
値が完全な文書か単なるコンテンツフラグメントか評価することができます。
文字データから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
AStype
)
ここで、type
は、character
、character varying
、text
(またはこれらの別名)を取ることができます。
この場合も、標準SQLに従ってxml
と文字列型間の変換を行うためにはこの方法しかありません。
PostgreSQLでは単に値をキャストすることが可能です。
XMLPARSE
やXMLSERIALIZE
を使わずに文字列値とxml
との間をキャストした場合、DOCUMENT
かCONTENT
かという選択が「XML option」セッション設定パラメータによって決定されます。
このパラメータは標準コマンド
SET XML OPTION { DOCUMENT | CONTENT };
または、よりPostgreSQLらしい構文
SET xmloption TO { DOCUMENT | CONTENT };
を使用して設定することができます。
デフォルトはCONTENT
ですので、すべての書式のXMLデータを扱うことができます。
デフォルトのXMLオプション設定では、文書型宣言を含む文字列をxml
に直接キャストすることはできません。
XMLコンテンツフラグメントの定義が受け付けないためです。
この操作を行う必要がある場合、XMLPARSE
を使用するかXMLオプションを変更してください。
クライアント側、サーバ側、および、これらを経由してやり取りされるXMLデータ内部で複数の文字符号化方式を扱う場合には注意が必要です。
テキストモードを使用してサーバに問い合わせを渡し、そしてクライアントに問い合わせ結果を渡す場合(これが通常のモードです)、PostgreSQLは、クライアントからサーバ、サーバからクライアントでやり取りされるすべての文字データを受信側の文字符号化方式に変換します。
22.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()
に対する問題として知られています。
xml
データ型は、比較演算子をまったく提供しないというところが他と異なります。
これは、XMLデータに対し、よく定義され、誰にとっても有用な比較アルゴリズムが存在しないためです。
この結果、xml
列を検索値と比べて行を取り出すことはできません。
したがって通常XML値には、IDなどの別のキーフィールドを一般的に付属させなければなりません。
XML値の比較を行うもうひとつの方法は、文字列に一度変換することです。
しかし、文字列比較は有用なXML比較方法といえないことに注意してください。
xml
データ型用の比較演算子がありませんので、この型の列に直接インデックスを作成することはできません。
XMLデータを高速に検索することが望まれるなら、その表現を文字列型にキャストし、それをインデックス付けするか、または、XPath式をインデックス付けするかという対策をとることができます。
当然ながら、インデックス付けされた式で検索されるよう実際の問い合わせを調整する必要があります。
PostgreSQLのテキスト検索機能を使用して、XMLデータの全文検索速度をあげることもできます。 しかし、PostgreSQL配布物では必要な前処理を未だサポートしていません。