無料PHPプログラム

MySQL 5.1 リファレンスマニュアル :: 11 関数と演算子 :: 11.9 XML 関数
« 11.8 キャスト関数と演算子

11.10 その他の関数 »
Section Navigation      [Toggle]
  • 11 関数と演算子
  • 11.1 演算子
  • 11.2 制御フロー関数
  • 11.3 文字列関数
  • 11.4 数字関数
  • 11.5 日付時刻関数
  • 11.6 MySQL が使用するカレンダーは ?
  • 11.7 全文検索関数
  • 11.8 キャスト関数と演算子
  • 11.9 XML 関数
  • 11.10 その他の関数
  • 11.11 GROUP BY 句との関数および修飾子の使用

11.9. XML 関数

このセクションでは 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 エレメントにマッチします。

  • その特性のひとつ以上の値に基づいたエレメントにマッチすることも可能です。これは、シンタックス tag[@attribute="value"] を用いて行います。例えば、XPath 式 //b[@id="idB"] は、フラグメント <a><b id="idA"/><c/><b id="idB"/></a> の 2 番目の b エレメントに一致します。attribute="value" を持ついかなるに対しても一致するには、XPath 式 //*[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() 関数を要求したりするよりより単純です。

Copyright c 1997, 2010, Oracle and/or its affiliates. All rights reserved. Legal Notices
Top / Previous / Next / Up / Table of Contents
© 2010, Oracle Corporation and/or its affiliates

無料CGI PHPスクリプト | 新着情報スクリプト | 営業日カレンダー | PHPマニュアル | MySQLマニュアル | PEARマニュアル

Copyright (c) 2010 jmcodex.com All rights reserved.