モンスターカレンダー

« 2010年1月
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

xmllibの最近のブログ記事

xmllib また使ってみる

| コメント(0)

よく使うような使いかた。

あるXMLデータを加工する。DOMです。




appleredfood


pikminredcreature?


pikminyellowcreature?


goldenkiwiyellowfood


lemonyellowfood


cucumbergreenfood

--------------------------------------------------------------------------------

(1)とりあえず全データを配列に入れる。

■スクリプト

require_once("XML/Parser.php");
define("CHAR_CODE", "EUC-JP");
 echo "";
 echo '';
 echo "";
 test1();
 echo "";
 echo "";

//すべてよみこみ、配列化
function test1(){

$doc = domxml_open_file("xmltest31.xml",
DOMXML_LOAD_DONT_KEEP_BLANKS); //不要な空白等除去

$color_nodes = $ctx->xpath_eval("/alldata/data");
$elements = $color_nodes->nodeset;
foreach ($elements as $data) {
 $nodes = $data->child_nodes();
 foreach ($nodes as $node) {
 $array[$node->tagname] = $node->get_content();
}
 $data_array[] = $array;
}

print_r($data_array);
}

■実行結果

Array (
[0] => Array ( [name] => apple [color] => red [kind] => food )
[1] => Array ( [name] => pikmin [color] => red [kind] => creature? )
[2] => Array ( [name] => pikmin [color] => yellow [kind] => creature? )
[3] => Array ( [name] => golden kiwi [color] => yellow [kind] => food )
[4] => Array ( [name] => lemon [color] => yellow [kind] => food )
[5] => Array ( [name] => cucumber [color] => green [kind] => food )
)

--------------------------------------------------------------------------------

(2)特定の条件のデータを配列に入れる。
XPathを使用して絞りこむ

■スクリプト

function test2(){

$doc = domxml_open_file("xmltest31.xml",
DOMXML_LOAD_DONT_KEEP_BLANKS); //不要な空白等除去

$ctx = xpath_new_context($doc);

$target = 'red';
$color_nodes = $ctx->xpath_eval("/alldata/data/color[text()='" . $target . "']"); //color="red"を抽出
$elements = $color_nodes->nodeset;
foreach ($elements as $element) {
 $node = $element->parent_node(); //親=dataノード取得
 $nodes = $node->child_nodes();
 foreach ($nodes as $val) {
  $array[$val->tagname] = $val->get_content();
 }
$data_array[] = $array;
}
print_r($data_array);
}

■実行結果

Array (
[0] => Array ( [name] => apple [color] => red [kind] => food )
[1] => Array ( [name] => pikmin [color] => red [kind] => creature? )
)

--------------------------------------------------------------------------------

(3)特定の条件のデータを配列に入れる:日本語データの場合

いろいろ試してみたところ、UTF-8で比較する必要があるようだ。
DOM関数を使用した時点でUTF-8となってしまう?
どこかで指定できるのかとマニュアル見てみたが、分からず。




りんごあかたべもの


ピクミンあかいきもの?


ピクミンきいろいきもの?


ゴールデンキウイきいろたべもの


レモンきいろたべもの


きゃべつみどりたべもの

■スクリプト

function test3(){

$doc = domxml_open_file("xmltest31.xml",
DOMXML_LOAD_DONT_KEEP_BLANKS); //不要な空白等除去

$ctx = xpath_new_context($doc);

$target = 'きいろ';
$target = mb_convert_encoding($target, "UTF-8", "EUC-JP"); //文字コード変換
$color_nodes = $ctx->xpath_eval("/alldata/data/color[text()='" . $target . "']");

$elements = $color_nodes->nodeset;
foreach ($elements as $element) {
 $node = $element->parent_node(); //親=dataノード取得
 $nodes = $node->child_nodes();
 foreach ($nodes as $val) {
//内部文字コードに変換
  $tag = mb_convert_encoding($val->tagname, "EUC-JP", "UTF-8");
  $cont = mb_convert_encoding($val->get_content(), "EUC-JP", "UTF-8");
  $array[$tag] = $cont;
 }
$data_array[] = $array;
}
print_r($data_array);
}

■実行結果

Array (
[0] => Array ( [name] => ピクミン [color] => きいろ [kind] => いきもの? )
[1] => Array ( [name] => ゴールデンキウイ [color] => きいろ [kind] => たべもの )
[2] => Array ( [name] => レモン [color] => きいろ [kind] => たべもの ) )
)

php:xmllibを使ってみる(続き)

| コメント(0)

(続き)
5.th,tdに属性追加
ルートノードに追加したのと、結局は同じことをする。
ただちょっとはまったのは、EUCでコードを書いているのに XMLLIBでは内部エンコーディングがUTF‐8なのに気づかず、日本語の取得でうまくいかなかった。。。mb_convert_encodingを使って下さい。

(1)スクリプト

function sub_func(){

$doc = domxml_open_file("xmltest.xml");
$root = $doc->root();

//ルートノードに widthという名称の属性を308という値でセットする
$root->set_attribute("width", "308");
//以下、同様に属性セット
$root->set_attribute("cellspacing", "0");
$root->set_attribute("cellpadding", "0");
$root->set_attribute("border", "1");

//セルのbgcolor設定のための配列
$bgcolor_array = array("あか"=>"red", "きいろ"=>"yellow", "みどり"=>"lightgreen", "むらさき"=>"violet");

$tr_array = $doc->get_elements_by_tagname("tr");
$i = 0;
//trの数だけ処理
while ($i  $tr = $tr_array[$i];
 $th = $tr->first_child(); //th
 $thc = $th->first_child();
 $thc_value = $thc->node_value();
 //取得した値("あか"など)を文字コ‐ド変換する
 $thc_value = mb_convert_encoding($thc_value, "EUC-JP", "UTF-8");
 //配列からbgcolor取得
 $attr = $bgcolor_array[$thc_value] ;
 //thの属性セット
 $th->set_attribute("bgcolor", $attr);
 $th->set_attribute("width", "80");

 $td = $tr->last_child(); //td
 //tdの属性セット
 $td->set_attribute("width", "220");

 $i++;
}

echo "

";
//修正した文書 doc を展開して表示
echo htmlspecialchars($doc->dumpmem());
echo "
";

}

(2ブラウザからの実行結果html) [→見る]

               
あかりんご いちご ピクミン
きいろバナナ レモン ゴールデンキウイ ピクミン
みどりきゅうり きゃべつ キウイ
むらさきナス ピクミン

※「XMLでは空白や改行もノードとみなす。」のですが、読みこむときに
$doc = domxml_open_file("xmltest31.xml",DOMXML_LOAD_DONT_KEEP_BLANKS);

と指定すれば、余分な空白、改行は削除してくれました。他にも
DOMXML_LOAD_PARSING
とか、いろいろ指定できるようです。

php:xmllibを使ってみる

| コメント(0)

とあるxmlデータを加工する。
xmlデータは、htmlのタグを用いて書かれたテーブルである。widthなどの属性をタグに付加する。

--------------------------------------------------------------------------------

1.最終目標html [→見る]



















あか りんご いちご ピクミン
きいろ バナナ レモン ゴールデンキウイ ピクミン
みどり きゅうり きゃべつ キウイ
むらさき ナス ピクミン

2.XML

xmltest.xml



 
  
  
 
 
  
  
 
 
  
  

 
 
  
  
 
あかりんご いちご ピクミン
きいろバナナ レモン ゴールデンキウイ ピクミン
きゅうり きゃべつ キウイ
むらさきナス ピクミン

(注:見やすいようにインデントしていますが、実際はインデントも改行もしていません。XMLでは空白や改行もノードとみなす。ここでは処理を単純化するためそれらはファイルに含まれていないものとします。)

↑「XMLでは空白や改行もノードとみなす。」のですが、読みこむときに
$doc = domxml_open_file("xmltest31.xml",
DOMXML_LOAD_DONT_KEEP_BLANKS);

と指定すれば、余分な空白、改行は削除してくれました。他にも DOMXML_LOAD_PARSING
とか、いろいろ指定できるようです。

--------------------------------------------------------------------------------

3.とりあえず読みこんでみる

(1)スクリプト

require_once("XML/Parser.php");
echo "";
echo '';
echo "";

sub_func();
echo "";
echo "";

function sub_func(){

//XMLファイル読みこみ
$doc = domxml_open_file("xmltest.xml");
//ルートノード取得
$root = $doc->root();
//ルートノードの名称表示
echo "root : " . $root->node_name();
}
>

(2)ブラウザからの実行結果

root : table

無事ルートノード

が取得できているようだ。

--------------------------------------------------------------------------------

4.ルートノードに属性追加

(1)スクリプト

function sub_func(){

$doc = domxml_open_file("xmltest.xml");
$root = $doc->root();

//ルートノードに widthという名称の属性を308という値でセットする
$root->set_attribute("width", "308");
//以下、同様に属性セット
$root->set_attribute("cellspacing", "0");
$root->set_attribute("cellpadding", "0");
$root->set_attribute("border", "1");

echo "

";
//修正した文書 doc を展開して表示
echo htmlspecialchars($doc->dumpmem());
echo "
";

}

(2)ブラウザからの実行結果html [→見る]

width="300" cellspacing="0" cellpadding="0" border="1">                                        
あかりんご いちご ピクミン
きいろバナナ レモン ゴールデンキウイ ピクミン
みどりきゅうり きゃべつ キウイ
むらさきナス ピクミン

無事、赤字の属性が追加されている。

--------------------------------------------------------------------------------

5.th,tdに属性追加

(続く)

php:xmllibを入れる

| コメント(0)

xml-dom拡張モジュ-ルを使う必要にせまられた。
PHP再インスト-ルだ。

(1)前準備
・Apacheを止める。
・PostgreSQLを止める。
・現在の/usr/local/lib/phpをコピー(この下にPear・Smartyのモジュールがたくさんあるので、移動はしなかった。現在の環境のバックアップ)。またphp.iniも念のためコピー。
・Apacheのlibexecの下のモジュールを名前を変えてコピー(現在の環境のバックアップ)

(2)libxmlインストール
・http://xmlsoft.orgから libxml2-2.6.11 を入手。

$ tar xzvf libxml2-2.6.11.tar.gz
$ cd libxml2-2.6.11
$ ./configure
$ su -
# make
# make install

このあと

# make tests

とする。(INSTALL に記述してあった)

(3)PHP再インストール

・php-4.3.8 を入手。

$ tar xzvf php-4.3.8.tar.gz
$ cd php-4.3.8
$ ./configure --with-dom --with-zlib-dir --with-pgsql --without-mysql --with-apxs2=/usr/local/apache2/bin/apxs --enable-mbstring --enable-mbregex
$ su -
# make
# make install

(4)起動など
・php.ini を コピーしたものからもどす
・Apacheを起動
・PostgreSQLを起動

phpinfo()で確認して完了!