サポンテ 勉強ノート

サポンテの勉強ノート・読書メモなどを晒します。

PHP における XML 操作に入門してみる

はじめに

試験勉強です。

PHP における XML 操作にはいくつもの道がありますが、その中から XML パーサ関数群 を勉強してみます。

しかし PHP5 から登場した SimpleXML や DOM エクステンションの人気のおかげで、それらに関する記事ばかりで PHP マニュアル公式にもたいしたサンプルコードが載っていませんし、ネットで探すのも大変でした。

これら関数は「SAX(Simple API for XML)」と呼ばれているようです。検索する際は SAX という単語を併用すると良いかもしれません。SAX は PHP4 では Expat ライブラリーをベースとして、PHP5 からは libxml2 ライブラリーがベースとなっています(source)。

xml_parse() の項目にある User Contributed Notes のサンプルがもっとも参考になりそうです。

これを写経したり、マニュアルのほかのページを参照しながらもろもろを考慮すると、シンプルに試すには以下のような簡単なサンプルが役に立つと思われます。

プログラム中の XML データについては以下のページのものを参考にしました。

参考: PHP 開発者のための XML: 第 1 回 PHP での XML を 15 分で学ぶ

サンプル

<?php
$xmlContents = <<<END_OF_XML
<books><book>
  <![CDATA[<b>Hello,world!</b>]]>
   <title>Great American Novel</title>
   <characters>
    <character>
     <name>Cliff</name>
     <desc>really great guy</desc>
    </character>
    <character>
     <name>Lovely Woman</name>
     <desc>matchless beauty</desc>
    </character>
    <character>
     <name>Loyal Dog</name>
     <desc>sleepy</desc>
    </character>
   </characters>
   <plot>
    Cliff meets Lovely Woman.  Loyal Dog sleeps, but wakes up to bark
    at mailman.
   </plot>
   <success type="bestseller">4</success>
   <success type="bookclubs">9</success>
  </book>
  <?php echo 'Processed in "pi_handler"' . "<br />\n"; ?>
  <book><![CDATA[This is Error.]]>
</books>
END_OF_XML;
// ※ この XML はサンプルのため、見た目悪くしてあり、誤りも含めてあります。

$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
xml_set_element_handler($p, 'start_tag_handler', 'end_tag_handler');
xml_set_character_data_handler($p, 'char_handler');
xml_set_processing_instruction_handler($p, 'pi_handler');

function start_tag_handler($parser, $data, $attribs)
{
    echo 'start_tag_handler:' . $data . "<br />\n";
}

function end_tag_handler($parser, $data)
{
    echo 'end_tag_handler:' . $data . "<br />\n";
}

function char_handler($parser, $data)
{
    echo 'char_handler:' . $data . "<br />\n";
    // タグとタグの間の空白でもこのハンドラがコールされることを確認してください。
    // 1行目の <books> と <book> が隣接しているところでコールされないことも確認
    // してください。
}

function pi_handler($perser, $target, $codes)
{
    if ($target == 'php') {
        eval($codes);
    }
}

$parseResult = xml_parse($p, $xmlContents);
if (!$parseResult) {
    echo xml_error_string(xml_get_error_code($p));
    echo ' in line ' . xml_get_current_line_number($p);
    echo ' and column ' . xml_get_current_column_number($p);
}
xml_parser_free($p);

かなり低レベルなパースを行うようで、これをそのまま業務に使用するのは余計なコードが増えそうです。SimpleXML や DOM の登場が喜ばれるのも解る気がします。

写経におススメ

PHP SAX Parser Example