PHP5でxml文書をパースする方法

このQ&Aのポイント
  • PHP5でxml文書をパースする方法について解説します。指定したURLのXMLデータを読み込み、商品情報を配列に格納する方法を紹介します。
  • 問題は、<option>タグが抜けている場合に、次の商品の<option>データが前の商品の<option>データとして配列に入ってしまうことです。
  • そこで、<item>タグを1つずつ取得し、各<item>の中の<option>にアクセスする方法を検討しています。しかし、firstChild以降のChildにはどうやってアクセスすれば良いのかわかりません。
回答を見る
  • ベストアンサー

PHP5でxml文書をパースする方法

<?xml version="1.0"?> <root> <items>  <item>   <id>1</id>   <name>商品(赤)</name>   <price>1500</price>   <color>red</color>   <size>8</size>   <option>A</option>  </item>  <item>   <id>2</id>   <name>商品(青)</name>   <price>700</price>   <color>blue</color>   <size>3</size>  </item>  <item>   <id>3</id>   <name>商品(緑)</name>   <price>1200</price>   <color>green</color>   <size>5</size>   <option>C</option>  </item> </items> </root> 上記のようなXMLデータをPHPでパースし、 1つずつ、配列に入れていきたいと考えていますが、 問題なのは、 上から2番目の商品(青)には、<option>データが無いということです。 これは、この<option>が、オプションが有る時にだけ存在するタグだからです。 //----------------------------- <?php $doc->load($url); //上記xmlデータのあるURL:$url $array = array(); $i = 1; while($i <= 3){  //実際には、もっと商品数はあります。ここでは例として、3。  //配列の初期化  $item_array = array();  $items = $doc->getElementsByTagName('id');  $item_array['id'] = $items->item($i)->nodeValue;  $items = $doc->getElementsByTagName('name');  $item_array['name'] = $items->item($i)->nodeValue;  //*  //*同様のコードが続く  //*  $items = $doc->getElementsByTagName('option');  $item_array['option'] = $items->item($i)->nodeValue;  //*  //*同様のコードが続く  //*  //商品データが詰まった配列を、さらに配列に入れる  $array[] = $item_array; } //全ての商品のデータが詰まった配列を表示する。 print_r($array); ?> //----------------------------- このようなことがしたいわけです。 なお、タグ名を$tag_array = array('id','name',,,,,'option',,,)として、 foreach($tag_array as $tag){  $items = $doc->getElementsByTagName($tag);  $item_array[$tag] = $items->item($i)->nodeValue; } という風にした方が冗長ではないかとは思いますが、 それは、まぁ横に置いておきまして、 このコードで問題なのは、<option>が途中、つまり2番目で抜けると、 3番目の<option>データが、2番目の商品の<option>データとして配列に入ってしまうことです。 上から順に詰めて、配列に格納されてしまい、困っている、ということです。 <option>データが無い場合は、「ナシ」とでもしておきたいのですが、 どうしたら良いでしょうか? <item>を1つずつ   $items = $doc->getElementsByTagName('item'); で取得して、 各<item>の中の、<option>にアクセスする、なんて方法があるとベストなのですが、 そんな方法はありますでしょうか? firstChildですと、<item>の場合、<id>になってしまうため、<option>にはアクセスできません。 firstChild以降のChildには、どうやってアクセスしたら良いのでしょうね? どなたか、宜しくお願い致します。

  • PHP
  • 回答数8
  • ありがとう数8

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

getElementsByTagNameが返すのは、DOMNodeListクラスで、 http://www.php.net/manual/ja/class.domnodelist.php DOMNodeListクラスは、lengthというプロパティを持っています。 <?php $items = $dom->getElementsByTagName('item'); $results(); $item_props = array('id'=>null, 'name'=>null, 'price'=>null, 'color'=>null, 'size'=>null, 'option'=>null); $item_keys = array_keys($item_props); for($i=0; $i<$items->length; $i++){ $item_array = array(); /* 下記が返すのはDOMNode http://www.php.net/manual/ja/class.domnode.php */ $item = $items->item($i); //DOMNodeにはchildNodesプロパティがある $children = $item->childNodes; for($j=0; $j<$children->length; $j++){ $child = $children->item($j); $name = $child->nodeName; //念のため小文字にしてみる $name = strtolower($name); if(in_array($name, $item_keys)){ $item_array[$name] = $child->nodeValue; } } $results[] = array_merge($item_props, $item_array); //初期値にマージしてやればなければ初期値が入る } ?> とか、ですかね。

nbsp0606
質問者

お礼

非常に分かりやすい回答をありがとうございます。 xml文書のパースの仕方には色々な方法があるようなので、 質問文では、とりあえず、私のしたいことを書かせて頂きました。 質問文に挙げたxml文書の例は、あくまで1例で、 実際にはもっと階層が深かったりと複雑なため、 どのようなxml文書でも対応できる、根本的な理解と、 それに基づいた方法を教えて頂けると良いなと考えていました。 また、私の好き好き(多くの場合、知識がないことによる食わず嫌い)にも よるかとは思いますが、 こちらの回答の方法が私には合っていると感じました。 xmlのパースの方法には、 simpleXML、DOM, XPathを使用した方法、などなど 色々あるようですが、 今までの所、三者三様の回答をして頂き、 比較しながら勉強させて頂きました。 どの方法でも、目的は果たせる、 しかし、長所短所がそれぞれにはありそうだなと思っています。 もし、この辺りのことについて、ご存知でしたら教えて頂けると嬉しいです。 それと、細かいことになりますが、数点質問をさせて下さい。 (1)$results(); とありましたが、 これは、配列変数として初期化しているということでしょうか。 初歩的な質問で、すみません。 なぜ初期化しているのか、ではなく、 配列の初期化にはこういう方法もあるんですね、というのが質問の主旨です。 (2)for($i=0; $i<$items->length; $i++){ のところで、 これは、foreach($items as $item){ とすることと意味はほぼ同じだと 考えてもよろしいでしょうか。 $items->length; を使わずに全件処理する場合には、foreachを使いたいかなと 個人的には思ったのですが、$items->length;を使うメリットがもしありましたら、 教えて下さい。 以上、おかげさまで、 NodeとNodelistの違いと、それらの扱い方について理解できたことで、 したかったことができるようになりました。問題解決です。

その他の回答 (7)

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.8

> あらかじめ、どの階層に、どんなタグがあるか分かっている場合に そのために、DTD や スキーマがあるんだけど、そこまで書く人は少ないわな。 XPath の場合、相対的な指定ができるから(上がることも可能)指標(必要な情報)が分かれば十分なんだけどね。 XPath の魅力を語っても仕方ない。イテレーションするか、ピンポイントで拾うか、XSL、XQuery でまとめて拾うかは、作成者の自由だし。 jQuery はバージョンいくつからか(元々その傾向はあったけれど)、Selecters API を採用している。あれはあれで使いやすい。 イテレーションの場合、Traversal API が使えると一番いいんだけど、PHP のライブラリとしてはまだ存在しないから、地味に 参照を辿っていくしかないのが残念。 何だかんだいって現状は、既存 API のバージョンアップと、各種モジュールの追加に期待するしかない。

nbsp0606
質問者

お礼

お返事が遅くなり、すみませんでした。 私にはまだ難しい用語もいくつかありましたが、 今回、とても勉強になりました。 特にXPathの記述例をいくつか挙げて頂けたことに感謝しています。 またXMLのことで分からないことがありましたら、教えて下さい。 以上、最後まで丁寧に付き合って頂き、本当にありがとうございました。

回答No.7

基本的には、文字列操作を行う場合に、文字列を上から順番に読み解いていくのか、正規表現を使うのかの違いぐらいの内容、と思ってもらえればいいのかなと思います。 または、JavascriptでDOMをゴリゴリ操作するのか、jQueryを使うのか、といったことに意味合いとしては似てると思います。 そう考えれば、XPath構文のわかりやすさは、yuu_xさんの仰るように、慣れです。 分かってしまえば、こまわりも効くし扱いやすい。 でも、XPathは、アクセス後に返してくるオブジェクトは、やっぱり基本のDOMNodeListだったりするわけですので、 そこから先の操作は基本のDOMDocumentを使ったときと同じ構文を使うので、 両方の特性を上手く組み合わせて、上手く付き合っていけばいいかなと。 下記、余談です。このXMLやHTMLを操作するためのライブラリって色々あるので、軽くご紹介を。 ライブラリの挙動を追えば、どうやって操作したらやりやすいのかとか、理解も深まるかも。 ■XML_Unserializer XMLを単純に配列に落とすだけだったら、PEARに、XML_Unserializerというライブラリもあって、 コレはもともとPHP4でも使えるように成っているので、DOMDocumentやXPathなんかは使われておらず、 最初に書いたような文字列操作と正規表現で行っています。 URL:http://pear.php.net/manual/ja/package.xml.xml-serializer.php ■CakePHP::XMLクラス CakePHPも自前で、XMLクラスといったものを搭載してますが、同様な理由(PHP4でも使える)で、 DOMDocumentやXPathは使ってなかったりします。 ■PHP Simple HTML DOM Parser コレもDOMDocumentやXPathなどは使ってないものです。jQueryと同じ構文でかけるので扱いやすい URL:http://simplehtmldom.sourceforge.net/ ■phpQuery こちらは上記の物とは違ってPHP5用ということで、内部的にはDOMElementを使っているし、XPathも使います。 http://code.google.com/p/phpquery/ ちょいちょいバグがあるので安定性はかけますが・・・

nbsp0606
質問者

お礼

回答ありがとうございます。 >XPathは、アクセス後に返してくるオブジェクトは、やっぱり基本のDOMNodeListだったりするわけですので、 そこから先の操作は基本のDOMDocumentを使ったときと同じ構文を使うので、 両方の特性を上手く組み合わせて、上手く付き合っていけばいいかなと。 なるほど、納得です。 よくわかりました。 また、余談の件も参考にさせていただきます。 大変、勉強になりました。

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.6

> ゴチャゴチャ w。 慣れるまではそう見えるかもしれない。どんな言語に対しても言えそうだけど、何が書いてあるか分からないうちは、ただの羅列にしか見えない。 ある程度までなら、省略構文が使えるので、それを利用してもいい。 > ある1つの<item>に対してメソッド実行すると、その<item>の中にある<price>1つが対象となる、 # items の直属の子の文脈順の最初の item の子の price ノード $xpath->evaluate('/root/items/item[1]/price')->item(0); // 半強制的に DOMNodeList が返る。最初の price ノードが必要な場合は、やや間抜けだけど、戻り値に対して item(0) を指定する。 # items の直属の子の文脈順最初の item の price の値 $xpath->evaluate('number(/root/items/item[1]/price)'); // PHP の場合、戻り値を指定できないため、キャストの手間が入るのは仕方ない。 # name 直下のみ $xpath->evaluate('string(/root/items/item[1]/name/text())');  <item>   <name>商品<ruby>しょうひん</ruby></name>  </item> # id=1 の item $xpath->evaluate('number(/root/items/item[id=1]/price)'); # 最初の item を軸とし、その直属の子 items を選択 $item = $xpath->evaluate('/root/items/item[1]')->item(0); $xpath->evaluate('child::items', $item);  <item>   <items>   </items>  </item>  <item/>  <item/> # $item の次の兄弟 item $xpath->evaluate('following-sibling::item[1]', $item); 後はマニュアルを見てください。 http://www.w3.org/TR/xpath/ - XML Path Language (XPath) Version 1.0 http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html - Document Object Model XPath

nbsp0606
質問者

お礼

補足、ありがとうございます。 お返事が遅くなり、すみません。 今回、XPathによる方法で対処することはほとんど考えていなかったのですが、 このように分かりやすく解説して頂けると、 そうかXPathも捨てたもんじゃないな、いやむしろ、素晴らしいかも?! と思えてきてしまいますね。 XPathではなく、DOMDocumentを使う方法で、 $items = $doc->getElementsByTagName('item');  foreach($items as $item){   $child_nodes = $item->childNodes;   foreach($child_nodes as $child){    //…この階層でのデータ抽出    foreach(…){     //…この階層でのデータ抽出     //…さらに深く掘り下げ、この下の階層にも手を伸ばし、     //…目的のタグのnodeValueの抽出を行う    }   }  } のように、今のところは書いているわけですが、 1階層で、複数のタグのデータを抽出できるならともかく、 深い階層まで手を伸ばしているにもかかわらず、 抽出するデータは1つか2つなんて場合には、 foreachの繰り返しばかりが増えて、なんだかコードが冗長になってしまい、 これで良いのだろうかと今、ちょっと疑問に思っています。 このような場合、 DOMDocumentではなく、やはりXPathを使用した方が良いのでしょうかね。 XPathだと、あらかじめ、どの階層に、どんなタグがあるか分かっている場合に、 遠回りせずに、直接そのノードへ手を伸ばせる感じがいいなと思っています。 色々と、すみません。 ご迷惑でなければ、また教えて下さい。

回答No.5

■$results();の件 ごめんなさい・・・完全にtypoです・・・・ $results = array(); と書きたかったのでした。 ■lengthプロパティを使ってforで回した理由 とりあえずPHPマニュアルのDOMNodeListクラスの最初の説明におきまして、 特にIteratorインターフェイスを実装していたりして無さそうだったので、 プロパティとメソッドから判断して書きました。 よく見たらforeachで回せるんですね。すみません。 ■SimpleXMLを使うのかDOMDocumentを使うのかXPathを使うのか 基本的にSimpleXMLは、入力されている各要素が分かっている、既知のフォーマットのときに使うと便利かなと。(RSSのパースとか) DOMDocumentは、読み込めるのがXMLだけではなく、HTMLも読むことが出来るので、 HTMLを読み込んで、抽出だとか置換だとかをするのに適しています。 丁度javascriptでHTMLを書き換えるような感じで使ったりします。 XPath、ある特定の属性をもつ要素をすべて抽出したいとかといった場合に便利ですね。 <?php $xpath = new DOMXPath($dom); $elements = $xpath->query("//*[@class='hoge']"); //class="hoge"のものを全部取得する ?> などといった記述をすれば、NodeListを返しますので、非常に簡単です。

nbsp0606
質問者

お礼

補足をありがとうございます。 お返事が遅れ、すみませんでした。 >■SimpleXMLを使うのかDOMDocumentを使うのかXPathを使うのか 分かりやすくまとめて頂き、非常に参考になりました。 ありがとうございます。 hogehoge78さんに教えて頂きました方法、 つまり、DOMDocumentを使って、 ループ処理で、ノードリストからノードを抽出し、 その中のノードをノードネームで判定して、 適宜、必要なデータを抜いていく、という方法が、 XML文書のパースの基本だと私は考えていまして、 実際に、その方法で、今、私の目の前にあるXML文書に対しても、 パースを試みようとして、以下のようなコードを書き、 問題なくプログラムを稼働させられています。 //--------------------------------------------  $items = $doc->getElementsByTagName('item');  foreach($items as $item){   $child_nodes = $item->childNodes;   foreach($child_nodes as $child){    //…この階層でのデータ抽出    foreach(…){     //…この階層でのデータ抽出     //…さらに深く掘り下げ、この下の階層にも手を伸ばし、     //…目的のタグのnodeValueの抽出を行う    }   }  } このコードは、動作的には問題ないのですが、 質問で挙げましたXML文書の例とは異なり、 もっと階層が深かったり、階層の深浅が複雑な文書の場合には、 コードの美しさの観点から、あまりオススメとは言えないのでしょうか? つまり、 foreachで回すようなコードを書くことになるDOMDocumentを使うよりも、 ピンポイントで必要箇所のみを容易に抜くことが可能なXPathを 使用する方がより実際的なのでしょうか? それとも、 私に知識がないために、このような考え方しかできていないのでしょうか。 質問で挙げたXML文書が単純だったので、今回は、 DOMDocumentによる方法を教えて下さったのだと思います。 私も当初、それを望んでいましたし、 また、その理解を得たおかげで、 今、こうして新たな疑問に直面できてもいるわけです。 というわけで、まとまりのない文章ですが、 何かアドバイスをして頂けますと、とても嬉しいです。 ご迷惑でなければ、また宜しくお願い致します。

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.4

XPath の利点は細かな調節ができるところにあるけど、平文 XML を配列に落とすだけなら、微調整もへったくれもない。 一点挙げるとすれば、getElementsByTagName はデフォルト空間の子孫ノードを全て拾うため、階層構造になったときに対応しきれなくなる。 > どのようなxml文書でも対応できる、根本的な理解と、それに基づいた方法を教えて頂けると良いなと考えていました。 XML の抽出には強力な XSL 及び XQuery があるため、抽出を自由に行いたいのであれば、そちらをお勧めします。 PHP では XSLT 1.0 しか利用できないけど、幸い、php:function を利用できるため、それほど不自由は感じない。 XML であることの利点は、階層構造は元より、環境を問わず(この利点は大きい)部分的な抽出、取り込み、関連付け、要素への重み付け等が自由に行えるところにある。 XML であることを放棄して、配列に落とすなら、PHP でロジックを組むことになるのだけれど、その辺は好きなように。 PHP だけで狭視的に利用するだけなら、CSV で十分だと思うんだけどね。必要に応じてデータベースに落とせるし。

nbsp0606
質問者

お礼

回答ありがとうございます。 >XPath の利点は細かな調節ができるところ そうですね、利点はそのようなところにあるのだと思っていました。 ただ、XPathのコード記述は見た目がゴチャゴチャしていて、 個人的には好きではないんですよね。 あと、処理速度は遅くならないのかなぁ、という気もしています。 >一点挙げるとすれば、getElementsByTagName はデフォルト空間の子孫ノードを全て拾うため、階層構造になったときに対応しきれなくなる。 ここ、そうでした、ここです。 この点で、「こんなことはできないんですか?」 という疑問がありまして、 つまり、 getElementsByTagNameをルート要素以外に対しても使いたいのですが、 そんなことはできないんですよね? というか、それと似たようなことを可能にしたのが、XPathなのでしょうか。 getElementsByTagName('price') というのを、<root>に対してメソッド実行すると、 各<item>の中にある<price>が 全てが対象になりますが、これを、 ある1つの<item>に対してメソッド実行すると、 その<item>の中にある<price>1つが対象となる、 みたいな感じで使えたらいいなと思っているわけです。 分かりにくかったら、すみません。

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.3

$ary = array( 'id' => 'number' ,'name' => 'string' ,'price' => 'number' ,'color' => 'string' ,'size' => 'number' ,'option' => 'string' ); $result = array(); $doc = new DOMDocument; $doc->loadXML($xml); $xpath = new DOMXPath($doc); foreach ($xpath->query('/child::root/child::items/child::item') as $item) { $params = array(); foreach ($ary as $name => $type) { $params[$name] = $xpath->evaluate("{$type}(child::{$name}/child::text())", $item); } $result[] = $params; } var_dump($result); 配列に置き換えるくらいなら、正直 simple_xml のが楽。 XML の構造が単純だし、文字列変換して eval したい気分にもなる。

nbsp0606
質問者

お礼

回答ありがとうございます。 DOMXPathを用いた方法を教えて頂き、大変参考になりました。 私に知識がないために、 本件において、DOMXPath を使う意義が分からなかったのですが、 もし何らかの意図なり目的があるようでしたら、教えてください。 最善かどうかは別として、 「他にも、こんな方法がありますよ」 という意味で、DOMXPathによる方法を教えて頂いたのでしょうか。 >配列に置き換えるくらいなら、正直 simple_xml のが楽。 とありましたから、 「回答NO.1の方法で良いが、他に方法はないかと問われれば、 DOMXPathによる方法を書きますが。」 といったお気持ちだったのでしょうか。 (失礼な書き方をしていたとしたら、すみません!) もし宜しければ、教えて下さい。

  • luka3
  • ベストアンサー率74% (291/392)
回答No.1

simplexml_load_file を使います。 -- テストソース $xml = simplexml_load_file('sample.xml'); print_r($xml); print $xml->items->item[0]->option; print isset($xml->items->item[0]->option)? "true":"false"; print isset($xml->items->item[1]->option)? "true":"false"; -- 出力結果(カッコなど整形してます) [items] => SimpleXMLElement Object  [item] => Array   [0] => SimpleXMLElement Object    [id] => 1    [name] => 商品(赤)    [price] => 1500    [color] => red    [size] => 8    [option] => A   [1] => SimpleXMLElement Object    [id] => 2    [name] => 商品(青)    [price] => 700    [color] => blue    [size] => 3   [2] => SimpleXMLElement Object    [id] => 3    [name] => 商品(緑)    [price] => 1200    [color] => green    [size] => 5    [option] => C A true false

nbsp0606
質問者

お礼

大変わかりやすい回答をありがとうございます。 >simplexml_load_file を使います。 こちらの方法について、よく分かりました。 ありがとうございます。 childNodesを用いた方法による回答を想定していましたが、 教えて頂いた方法でも、私の希望を叶えてくれますね。 とても勉強になりました。 ありがとうございます。 一方で、 simplexmlを使わない方法でも、 何か方法がないか知りたいと思っています。 もしどなたかご存知でしたら、教えて下さい。

関連するQ&A

  • XMLのタグの有無をPHPで判定したい。

    example1.xml ----------------------- <item>  <color>red</color>  <omake>candy</omake> </item> ----------------------- example2.xml ----------------------- <item>  <color>black</color> </item> ----------------------- 上記はXMLファイルの2パターンを示したものです。 商品(item)によって、オマケ(omake)があったりなかったりします。 オマケがない時には、タグ自体存在しません。 なので、タグがない時に、そのデータをDOMで取得しようとすると、 エラーが吐かれます。 Notice: Trying to get property of non-object in~~~ 私がしたいことは、 タグがない場合には、値を取得しない。 という分岐をさせることです。 例えば、 $items = $doc->getElementsByTagName('color'); if(isset($items)){echo $items->item(0)->nodeValue;} こんな感じで考えたのですが、ダメでした。 タグが無くても、$itemsはNULLではないため、 if文の中に入ってしまい、 結局、$items->item(0)->nodeValue; を通過しようとして、 Notice: Trying to get property of non-object in~~~ が吐かれます。 ($itemsは、object(DOMNodeList)#3 (0) { }といった内容で、NULLではない。) また、 if(isset($items->item(0)->nodeValue)){  echo $items->item(0)->nodeValue; } のようにすると、 isset()のところで、やはり、 $items->item(0)->nodeValue を通過しようとして、 Notice: Trying to get property of non-object in~~~ が吐かれます。 こういった場合、どうしたら良いのでしょうか。 宜しくお願いします。 (PHP5の環境です。)

    • ベストアンサー
    • PHP
  • getElementsByTagNameのタグの個数を調べるには

    javascriptでxmlデータを扱ったページを作成しています。 以下のようなデータです。 getElementsByTagNameでitemタグの下にいくつタグがあるかを 調べるにはどうしたらいいのですか? getElementsByTagNameにlengthは使えないので。。 データ: <markers> <item No="001"> <id>A01</id> <shu1>you</shu1> <name>aiueo</name> <price>1000</price> <md>1</md> <as>2</as> <imagepass>bbb.gif</imagepass> <shousaiaddr>http://www.yahoo.co.jp/</shousaiaddr> </item>     <item No="002">      ・・・

  • javascriptでxmlデータの取得

    googleガジェットでamazonAPIを使ったものを作ろうと思うのですが[FormattedPrice]のデータが取得できません。 + <Item> - <OfferSummary> - <LowestNewPrice> <Amount>2359</Amount> <CurrencyCode>JPY</CurrencyCode> <FormattedPrice>¥ 2,359</FormattedPrice> </LowestUsedPrice> </OfferSummary> </Item> こうなっている中で<FormattedPrice>の値を取り出すにはどうすればいいのでしょうか? var entryElements = doc.getElementsByTagName('Item');  for (var i = 0; i < entryElements.length; ++i) {   var entry = entryElements[i];   var entryData = {};   entryData['price'] = entry.getElementsByTagName('FormattedPrice')[0].childNodes[0].nodeValue; } とやっても駄目でした。

  • smartyのforeachの使い方

    仮に$strが以下のような配列を持っている場合smartyのtpl側で 出力させたいのですがうまくいきません。 Array ( [0] => Array ( [id] => 1 [name] => 名前 [sub_id] => Array ( [0] => 12 [1] => 13 ) [sub_name] => Array ( [0] => あああ [1] => いいい ) [sub_cnt] => Array ( [0] => 5 [1] => 5 ) ) [1] => Array ( [id] => 1 [name] => 名前 ) ) sub_***は配列が存在するものとしないものがあります。 そしてtpl側は {foreach item=items from=$str} <ul id="side{$items.id}"> {foreach item=item from=$items} <li><a href="index.php?id={$item.sub_id}">{$item.sub_name} ({$item.sub_cnt})</a></li> {/foreach} </ul> {/foreach} とforeachを重ねてみたのですがsub_***の値が表示されない 状態です。 複雑な配列なのですがこの場合どうすればうまく表示させれるの でしょうか?

    • ベストアンサー
    • PHP
  • JQueryでxmlのデータを取得する。

    以下のようになっているxmlのデータがあります。 --------------------- <item> <name1>0</name1> <name2>1</name2> <name3>0</name3> </item> --------------------- <item>~</item>の中の 子ノードのタグ名とテキストデータをJQueryを使って取得したいと考えています。 上記のように、<name1><name2><name3> とタグ名がバラバラなので 配列で取得したいのですが。やり方がわかりません。 どなたかご教授ください。

    • ベストアンサー
    • AJAX
  • phpmyadminからphpに読み込ませて配列化

    現在phpmyadminからphpに読み込みこんで配列化する勉強をしています。 syouhinテーブルの中にid name priceというものを用意しています。 $recordSet = mysql_query('SELECT * FROM syouhin'); while($data = mysql_fetch_assoc($recordSet)) { echo $data['id'],$data['name'],$data['price']; } このようにすれば用意しているもの、例えばidが1、nameがバナナ,priceが200、idが2、nameがバナナ,priceが200・・・・と全部でてくると思います。 これは$dataにこれらが入っているのだと思うですが、idが1のものをsyouhin1に格納しidが2のものをsyouhin2に格納するようにしたいのですがどうしたらいいでしょうか? すみません説明がへたくそでして。 プログラムは授業で勉強したばかりで配列が弱いので、丁寧に教えて頂けると嬉しいです。 ここの勉強もしておくべきという場所もありましたら教えて頂けると嬉しいです。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHP5でのXMLパーサーについて

    PHP5で $xml = simplexml_load_file($url)を使って ヤフーオークションAPIから帰ってきたデータを処理したいのですが、 titleは {$xml->item[0]->title}で取得できることがわかったのですが、 totalAuctionsなど@attributesの中のデータを取得することができません。 どのようにすればよいかご教授願います。 よろしくお願いします。 SimpleXMLElement Object (  [@attributes] => Array  (   [totalAuctions] => 3677   [totalPage] => 74   [curPage] => 1  )  [item] => Array  (   [0] => SimpleXMLElement Object   (    [auctionID] => *****    [title] => ******    [seller] => SimpleXMLElement Object     (      [id] => ***      [itemlist] =>http://api.auctions.yahoo.co.jp/AuctionWebService/V1/SellingList?sellerID=***      [rating] =>ttp://rating2.auctions.yahoo.co.jp/jp/show/rating?userID=***     )      [url] => http://********************************      [img]=>http://**********************************.jpg      [price] => **,000 円      [bids] => **      [endtime] => *月 **日 **時 **分      [reserved] => SimpleXMLElement Object       (       )      [option] => SimpleXMLElement Object      (       [0] =>      )     )   ) )

    • ベストアンサー
    • PHP
  • ランキング機能の実装

    group byを使って、詳細テーブルを集計してランキング表示するためのSElECT文を作成しています。購入数の多い順に商品を表示させるには、以下のSQL文をどのように修正すればいいですか? $sql = " SELECT details.item_id, details.price, details.amount SUM(details.price * details.amount) AS total, items.name FROM details JOIN items ON details.item_id = items.item_id GROUP BY details.item_id, details.price, details.amount, items.name ORDER BY amount ";

    • 締切済み
    • PHP
  • データベース ー どういうテーブル構造にしますか?

    管理者テーブル table admin admin int, adm_name text 商品テーブル table items item_id int, item_name text, item_price int と2つのデータテーブルがあった場合に 、誰がいつどんな変更をしたかを記録を取りたい場合、あなたならどういうふうに作りますか? itemsテーブルにカラムを増やしますか? 別テーブルでログ用のテーブルを増やしますか?

  • PHPでのXMLの編集・削除の方法

    XMLの編集・削除をPHPで行いたいと思っています。 その際に、どの要素なのかを指定したいと思うのですが なかなか方法が分からずに困っています。 調べてみて、Xpathを利用して指定し 削除をする時には DOMNode = DOMNode->removeChild(ノード) 編集する時には DOMNode->nodeValue = 値 と、いうものを利用すればいいのかな?と分かってきたのですが 実際、PHPに組み込んでみても、動いてくれず分からなくなっています。 【削除PHP】 foreach ($_POST['number'] as $key => $value){ $xpath = new DOMXPath($doc); $xpath_title = $xpath->query("//title[parent::record/@number=$value]"); //要素ノードの取得 $dataElement = $doc->getElementsByTagName("title")->item(0); //削除 $dataElement->removeChild($xpath_title) or die("削除できません。"); } 【編集PHP】 $xpath = new DOMXPath($doc); $xpath_title = $xpath->query("//record/@number=$session_number"); //値の変更 $session_title = $_SESSION["title"]; $xpath_title->title->nodeValue = $session_title; print $xpath_title->title->nodeValue; 【XML】 <renew>  <record number="000000">   <title>タイトル</title>   <paragraph>内容</paragraph>  </record> </renew> 字数制限の為に、コードも必要最低限だと思われるものしか 記述していません。これでは分からないという事であれば 追記で記述しますので、分かる方は是非教えてください。 よろしくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう