PHPでコロンを含むXML要素名を扱う方法

(1/1)
いままで XML を扱う際に、PHP 4.x では DOM XML を、PHP 5.x では SimpleXML を利用してきた。
これらは便利な関数群だが、XML要素名にコロン「」を含む場合、そのままでは扱うことができない。たとえば RSS 1.0 では、"dc:date" のように、コロンを含む要素名があり、処理に工夫が必要だ。

XML の要素名にコロン「」を含む場合、名前空間(name space)が関係してくる。
今回は、RSS 1.0 を題材に、Simple XML で名前空間を扱う方法を紹介する。

サンプル・プログラム「RSS 1.0 ビューア」

RSS 1.0 (RDF)を読み込み、その内容を表示するプログラムである。
冒頭で述べたように、コンテンツの更新日を示す要素 "dc:date" の処理で工夫が必要だ。

プログラムを実行する

ダウンロード(PHP 4/5/7)

サンプル・プログラムの解説:DOM XMLの場合

0160:     //PHP4用; DOM XML利用
0161:     if (isphp5over() == FALSE) {
0162:         $dom = read_xml($url);       //DOM XML利用
0163:         if (($rdf = $dom->get_elements_by_tagname('RDF')) == NULLreturn FALSE;
0164:         //channel情報の取得
0165:         $channel = $rdf[0]->get_elements_by_tagname('channel');
0166:         $node    = $rdf[0]->get_elements_by_tagname('title');
0167:         $arr['channel']['title'] = htmlspecialchars($node[0]->get_content());
0168:         $node    = $rdf[0]->get_elements_by_tagname('link');
0169:         $arr['channel']['link'] = htmlspecialchars($node[0]->get_content());
0170:         $item    = $rdf[0]->get_elements_by_tagname('item');
0171:         //item情報の取得
0172:         $i = 0;
0173:         while (isset($item[$i])) {
0174:             $node = $item[$i]->get_elements_by_tagname('title');
0175:             $arr['item'][$i]['title']       = htmlspecialchars($node[0]->get_content());
0176:             $node = $item[$i]->get_elements_by_tagname('link');
0177:             $arr['item'][$i]['link']        = htmlspecialchars($node[0]->get_content());
0178:             $node = $item[$i]->get_elements_by_tagname('description');
0179:             $arr['item'][$i]['description'] = htmlspecialchars($node[0]->get_content());
0180:             $node = $item[$i]->get_elements_by_tagname('date');
0181:             $arr['item'][$i]['date']        = htmlspecialchars($node[0]->get_content());
0182:             $i++;
0183:         }

RSS 1.0 の内容を配列変数に格納するユーザー関数が getRDF である。
内部では、PHP 4.x の場合と PHP 5.x の場合とで処理を分岐させている。

関数 get_elements_by_tagname では、要素名にコロンを含む場合、コロンの右側を認識する。そこで、get_elements_by_tagname('date') としてやれば、要素 "dc:date" の値を取得することができる。

なお、配列変数 $arr に代入する際にいちいち関数  htmlspecialchars  を適用しているのは、クロスサイトスクリプティング対策のためである。

サンプル・プログラムの解説:SimpleXMLの場合

0185:     //PHP5用; SimpleXML利用
0186:     } else {
0187:         $rdf = @simplexml_load_file($url);
0188:         if ($rdf == FALSE)  return FALSE;
0189:         if (! isset($rdf->item))  return FALSE;
0190:         //channel情報の取得
0191:         $arr['channel']['title'] = htmlspecialchars($rdf->channel->title);
0192:         $arr['channel']['link']  = htmlspecialchars($rdf->channel->link);
0193:         //item情報の取得
0194:         $i = 1;
0195:         while (isset($rdf->item[$i]->title)) {
0196:             $arr['item'][$i]['title']        = htmlspecialchars($rdf->item[$i]->title);
0197:             $arr['item'][$i]['link']         = htmlspecialchars($rdf->item[$i]->link);
0198:             $arr['item'][$i]['description']  = htmlspecialchars($rdf->item[$i]->description);
0199:             $node = $rdf->item[$i]->children(NS_dc);
0200:             $arr['item'][$i]['date']         = htmlspecialchars($node->date);
0201:             $i++;
0202:         }
0203:         $i--;
0204:     }

Simple XML の場合、"$rdf->item[$i]->dc:date" では要素の内容を取得することができない。名前空間を指定し、children メソッドを使う必要がある。

0024: //名前空間
0025: define('NS_dc',    'http://purl.org/dc/elements/1.1/');
0026: define('NS_rdf',   'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
0027: define('NS_xmlns', 'http://purl.org/rss/1.0/');

RSS 1.0 で使う名前空間は、あらかじめ定数で定義しておく。

children メソッドで子ノード $node を取得したら、"$node->dc" と指定することで、要素 "dc:date" の内容を取り出すことができる。

参考サイト

(この項おわり)
header