このセクションでは MySQL での XML と関連する機能について説明します。
--xml
オプションで呼び出して、mysql
および mysqldump クライアントの XML
フォーマットの出力を MySQL
から得ることは可能です。項7.7. 「mysql — MySQL コマンド ライン ツール」
および 項7.12. 「mysqldump — データベースバックアッププログラム」
を参照してください。
MySQL 5.1.5 からは、基礎的な XPath ( XML Path Language ) 機能を提供するふたつの関数を利用することができます。
これらの関数は現在もまだ開発途中ですのでご注意ください。MySQL 5.1 と今後のためにも、これらの関数や XML および XPath の機能を改良し続けていきます。これらについてご意見や質問のある方、また他のユーザからのアドバイスを得たい方は、MySQL XML User Forum をご覧ください。
ExtractValue(
xml_frag
,
xpath_expr
)
ExtractValue()
はふたつのストリング引数、XML
マークアップのフラグメント
xml_frag
、そして XPath 式
xpath_expr
(
locator とも呼ばれる )
を取り、XPath
式によってマッチされたエレメントの子である、最初のテキスト
ノードのテキスト ( CDATA
)
を戻します。これは、/text()
を付加した後に、xpath_expr
を使用してマッチを行うのと同様です。つまり、ExtractValue('<a><b>Sakila</b></a>',
'/a/b')
と
ExtractValue('<a><b>Sakila</b></a>',
'/a/b/text()')
は同じ結果を生成します。
複数のマッチが検出される場合、各マッチング エレメントの、最初の子のテキスト ノードの内容は、単一の、スペースで区切られたストリングとして ( マッチした順で ) 戻されます。
( 拡大された ) 式 —
に対して、マッチするテキスト
ノードが検出されない場合 —
どういう理由であれ、xpth_expr
が有効で、xml_frag
が適切に成型されていれば —
空のストリングが戻されます。空のエレメントでの整合と、整合するものがないのとは、区別はされません。これはデザインによるものです。
xml_frag
でマッチするエレメントが見つからなかったのか、またはマッチするエレメントはあったものの、非子テキスト
ノードを含んでいたのかを判断する必要があれば、XPath
count()
関数を使用する式の結果をテストしてください。例えば、次のように、これらのステートメントの両方が空のストリングを返す場合
:
mysql>SELECT ExtractValue('<a><b/></a>', '/a/b');
+-------------------------------------+ | ExtractValue('>a<>b/<>/a<', '/a/b') | +-------------------------------------+ | | +-------------------------------------+ 1 row in set (0.00 sec) mysql>SELECT ExtractValue('<a><c/></a>', '/a/b');
+-------------------------------------+ | ExtractValue('<a><c/></a>', '/a/b') | +-------------------------------------+ | | +-------------------------------------+ 1 row in set (0.00 sec)
しかし、次のように、実際にまっちするエレメントがあったのかを確認することはできます :
mysql>SELECT ExtractValue('<a><b/></a>', 'count(/a/b)');
+-------------------------------------+ | ExtractValue('<a><b/></a>', 'count(/a/b)') | +-------------------------------------+ | 1 | +-------------------------------------+ 1 row in set (0.00 sec) mysql>SELECT ExtractValue('<a><c/></a>', 'count(/a/b)');
+-------------------------------------+ | ExtractValue('<a><c/></a>', 'count(/a/b)') | +-------------------------------------+ | 0 | +-------------------------------------+ 1 row in set (0.01 sec)
ExtractValue()
は CDATA
のみを戻し、マッチング
タグに含まれるタグや、それらのコンテントは戻されません
( 次の例の、val1
として戻された結果を参照 ) 。
mysql>SELECT
->ExtractValue('<a>ccc<b>ddd</b></a>', '/a') AS val1,
->ExtractValue('<a>ccc<b>ddd</b></a>', '/a/b') AS val2,
->ExtractValue('<a>ccc<b>ddd</b></a>', '//b') AS val3,
->ExtractValue('<a>ccc<b>ddd</b></a>', '/b') AS val4,
->ExtractValue('<a>ccc<b>ddd</b><b>eee</b></a>', '//b') AS val5;
+------+------+------+------+---------+ | val1 | val2 | val3 | val4 | val5 | +------+------+------+------+---------+ | ccc | ddd | ddd | | ddd eee | +------+------+------+------+---------+
MySQL 5.1.8
からは、この関数は、contains()
との比較に現行の SQL の照合を使用します。(
以前は、バイナリ —
大文字小文字の区別あり —
比較が常に使用されていました。)
UpdateXML(
xml_target
,
xpath_expr
,
new_xml
)
この関数は、XML マークアップ
xml_target
の提示されたフラグメントの単一部を、新しい
XML フラグメント new_xml
に置き換え、その後チャージされた XML
を戻します。置換された
xml_target
の一部は、ユーザから提供された XPath 式
xpath_expr
にマッチします。xpath_expr
にマッチする式が検出されない場合、または複数のマッチが見つかった場合、この関数は独自の
xml_target
XML
フラグメントを戻します。3
つすべての引数はストリングでなければなりません
mysql>SELECT
->UpdateXML('<a><b>ccc</b><d></d></a>', '/a', '<e>fff</e>') AS val1,
->UpdateXML('<a><b>ccc</b><d></d></a>', '/b', '<e>fff</e>') AS val2,
->UpdateXML('<a><b>ccc</b><d></d></a>', '//b', '<e>fff</e>') AS val3,
->UpdateXML('<a><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val4,
->UpdateXML('<a><d></d><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val5
->\G
*************************** 1. row *************************** val1: <e>fff</e> val2: <a><b>ccc</b><d></d></a> val3: <a><e>fff</e><d></d></a> val4: <a><b>ccc</b><e>fff</e></a> val5: <a><d></d><b>ccc</b><d></d></a>
次は、いくつかの基本的な XPath 式の説明と例です :
/
tag
<
がルートのエレメントである場合にのみ、tag
/><
にマッチします。
tag
/>
例 :/a
は、最外部の ( ルート )
タグとマッチするため、<a><b/></a>
に一致を持ちます。このインスタンスでは他のエレメントの子になるため、<b><a/></b>
の内側 a
エレメントとは一致しません。
/
tag1
/tag2
<
の子と、tag1
/><
がルートのエレメントである場合にのみ、tag1
/><
にマッチします。
tag2
/>
例 :ルートのエレメント a
の子であるため、/a/b
は XML
フラグメント
<a><b/></a>
内の
b
エレメントとマッチします。このケースでは
b
はルートのエレメント (
従って他のどのエレメントの子でもない )
ため、<b><a/></b>
でマッチするものはありません。XPath
式もまた、<a><c><b/></c></a>
でマッチするものはありません。従って、b
は a
の子孫ですが、a
の子ではありません。
この構築は 3
つ以上のエレメントに拡張可能です。例えば、XPath
式 /a/b/c
は、フラグメント
<a><b><c/></b></a>
の c
エレメントに一致します。
//
tag
tag
のすべてのインスタンスと一致します。
例 ://a
は、次のうちのどの
a
エレメントとも一致します :
<a><b><c/></b></a>
;
<c><a><b/></a></b>
;
<c><b><a/></b></c>
//
は /
との結合が可能です。例えば、//a/b
は、フラグメント
<a><b/></a>
または
<a><b><c/></b></a>
のどれの b
エレメントともマッチします。
*
演算子は、どのエレメントともマッチする
「wildcard」
のように作用します。例えば、式
/*/b
は、XML フラグメント
<a><b/></a>
または
<c><b/></c>
のどの
b
エレメントともマッチします。しかし、b
は他のどれかのエレメントの子であるため、この式はフラグメント
<b><a/></b>
ではマッチを生産しません。ワイルドカードはどのポジションででも使用することができます
: 式 /*/b/*
は、それ自身がルートのエレメントでない
b
エレメントの、どの子ともマッチします。
複数のロケータが、|
( 論理和
OR
)
演算子を用いてマッチすることができます。例えば、XPath
式 //b|//c
は、XML
ターゲットのすべての b
および c
エレメントにマッチします。
その特性のひとつ以上の値に基づいたエレメントにマッチすることも可能です。これは、シンタックス
を用いて行います。例えば、XPath 式
tag
[@attribute
="value
"]//b[@id="idB"]
は、フラグメント <a><b
id="idA"/><c/><b
id="idB"/></a>
の 2 番目の
b
エレメントに一致します。
を持ついかなるに対しても一致するには、XPath
式
attribute
="value
"//*[
を使用します。
attribute
="value
"]
複数の属性値をフィルターにかけるには、単に複数の属性比較句を継続的に使用します。例えば、XPath
式 //b[@c="x"][@d="y"]
は、与えられた XML
フラグメントの各所で起こっている
<b c="x" d="y"/>
エレメントに一致します。
同じ特性が複数の値のうちのひとつとマッチするエレメントを見つけるには、|
演算子によってつながれた複数のロケータを使う必要があります。例えば、c
特性が値 23 もしくは 17 を持つ、すべての
b
エレメントをマッチするには、式
//b[@c="23"]|b[@c="17"]
を使用します。
XPath シンタックスのさらに詳しい説明や使用方法は、このマニュアルの対象範囲ではありません。決定的な情報については XML Path Language (XPath) 1.0 standard をご覧ください。XPath をご存知ない方、基本を復習したい方は Zvon.org XPath Tutorial を参照してください。複数の言語でご覧いただけます。
これらの関数にサポートされている XPath シンタックスは、現在、以下の制限の対象となっています :
ノード セット間比較 (
'/a/b[@c=@d]'
など )
はサポートされていません。const
が定数値のフォーム
[@
の唯一の比較は、現在可能です。サポートされている比較演算子は、同等と不等
( attribute
="const
"]=
と (!=
)
のみです。
相対ロケータ式はサポートされていません。XPath
式は、/
または //
で始まります。
::
演算子はサポートされていません。
「Up-and-down」 ナビゲーションは、パスがルート エレメントの「上」をリードする場合はサポートされていません。つまり、現在のエレメントのひとつ以上の祖先が同時にルート エレメントの祖先であり、与えたれたエレメントの祖先の継承上でマッチする式を使用することができません ( Bug#16321 参照 ) 。
次の XPath 関数はサポートされていません :
id()
lang()
MySQL 5.1.8 よりで前は、last()
関数はサポートされていません ( Bug#16318
参照 ) 。
local-name()
name()
namespace-uri()
normalize-space()
starts-with()
string()
substring-after()
substring-before()
translate()
次の軸はサポートされていません :
following-sibling
following
preceding-sibling
preceding
MySQL 5.1.10 からは、XPath 式は引数として
ExtractValue()
に渡され、UpdateXML()
が、XML
ネームスペース記号を採用してマークアップとの使用を有効にするエレメント
セレクタに、コロン文字 (
「:
」 )
を含むこともあります。例 :
mysql>SET @xml = '<a>111<b:c>222<d>333</d><e:f>444</e:f></b:c></a>';
Query OK, 0 rows affected (0.00 sec) mysql>SELECT ExtractValue(@xml, '//e:f');
+-----------------------------+ | ExtractValue(@xml, '//e:f') | +-----------------------------+ | 444 | +-----------------------------+ 1 row in set (0.00 sec) mysql>SELECT UpdateXML(@xml, '//b:c', '<g:h>555</g:h>');
+--------------------------------------------+ | UpdateXML(@xml, '//b:c', '<g:h>555</g:h>') | +--------------------------------------------+ | <a>111<g:h>555</g:h></a> | +--------------------------------------------+ 1 row in set (0.00 sec)
これは Apache
Xalan
と他のいくつかのパーサによって利用できるものに似ており、また、ネームスペース宣言または
namespace-uri()
や、local-name()
関数を要求したりするよりより単純です。