SimpleXMLでXMLの要素を参照する方法とは?

このQ&Aのポイント
  • phpのSimpleXMLを使用してXMLの要素を参照する方法について教えてください。
  • フォームから受け取ったキーワードを使用して、phpでXMLファイルを参照し、要素を出力する方法を知りたいです。
  • SimpleXMLを使用してXMLの要素を連想配列から参照する際のエラーについても解説していただきたいです。
回答を見る
  • ベストアンサー

phpのSimpleXMLでXMLの要素を参照したい。

フォームからキーワードを受け取り、それを、xmlを参照しながらphpで出力したいのですが、最後の最後でつまずきます。 ------------------ <?php $doc = new domDocument(); // DOMDocumentオブジェクトにより、インスタンスを生成 $doc->load("./beta.xml"); // ファイルからXML文書を読みこむ $kywd = $_REQUEST['kywd']; // フォームからデータを受け取る $nodelist = $doc->getElementsByTagName('keyword'); // 指定した要素名(keyword)の全ての要素を取得 foreach ($nodelist as $node) { // 各要素を参照 if($kywd == $node->textContent){ // もし、フォームから受け取ったデータが要素と一致したら $xurl = $node->namespaceURI; // 要素の名前空間URLを取得して$xurlに代入 $xml = simplexml_load_file("./beta.xml"); // SimpleXMLによってXMLファイルをパースし、simplexml_elementオブジェクトを作成する $parent = $xml->children("$xurl"); // 指定したノードの子ノードの配列を取得 $hairetsu = $parent[0]->children("$xurl"); //取得した配列素$hairetsuに代入 foreach($hairetsu as $key=>$value) { // ちゃんと連想配列になっているか、ためしに出力 print ($key."→".$value."<br />"); } // 連想配列になっていることを確認 print $hairetsu["title"]; // しかし、キーを指定して値を取得しようとすると、なぜか得られない。 } } ?> 問題は最後のほうです。連想配列になっていることは確かに確認できる(titleというキーも、その値もある)のですが、連想配列のキーから値を参照しようとすると、なぜか値がNULLになっていて表示できません。私は趣味でプログラミングをする程度なので、おそらく基本的なところで間違っているのだと思いますが、それがどこだか分かりません。お教え願えないでしょうか。

  • bunoo
  • お礼率57% (4/7)
  • PHP
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

#1>「キーワード」を参照して「タイトル」を得たい 余計なお世話かもしれませんが、 この場合、「タイトル」は、キーワードの親ノードの子ノードなので、いちいち、名前空間で限定する必要は無いように思います。 そして、DOMだけで操作できます。 例えばこんな感じ。 ---------------------------------------------------------------- <?php #encoding UTF-8 $doc = new domDocument(); $doc->load("./beta.xml"); $kywd = 'ポータルサイト';#$_REQUEST['kywd']; $nodelist = $doc->getElementsByTagName('keyword'); foreach ($nodelist as $node) { if($kywd == $node->nodeValue){ $titles = $node->parentNode->getElementsByTagName('title'); $title = $titles->item(0)->nodeValue; print mb_convert_encoding($title,"SJIS","UTF-8") . "\n";#必要に応じて文字コード変換 } } ?> ---------------------------------------------------------------- 元のプログラム(を試してはいませんが)でうまくいかない理由は、多分文字コードに起因するもの、あるいはsimpleXMLの構造の勘違いではないかと思います。

bunoo
質問者

お礼

おお!できました! なにぶん、プログラミング初心者なので、私の知識では質問したプログラム以外の手段が思いつかなかったのです。 私も、「我ながら回りくどいプログラムだなー」と思っていたので本当に助かりました!ありがとうございました。

その他の回答 (1)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

beta.xml を補足していただけないでしょうか

bunoo
質問者

お礼

すいません。まだ「教えてgoo」でID取ったばかりで、使い方をよく理解していないのですが、「補足」に書いた内容が間違っていたので訂正します ------------ 例えば、フォームから「ポータルサイト」というキーワードを受け取ったときに、「キーワード」と言う<uri:keyword>を持っているノードと同じ名前空間URIをもつ<uri:title>の要素(この場合、「ヤフー」と「グーグル」(「ぐーぐる」ではない))を取り出したいのです。簡単に言えば、「キーワード」を参照して「タイトル」を得たいのです。

bunoo
質問者

補足

すいません。字数制限のために書き込めないでいました。 ----- [beta.xml] <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <sites> <uri:site xmlns:uri="http://www.yahoo.co.jp/"> <uri:title>ヤフー</uri:title> <uri:keyword>ポータルサイト</uri:keyword> <uri:keyword>ヤフージャパン</uri:keyword> </uri:site> <uri:site xmlns:uri="http://www.google.co.jp/"> <uri:title>グーグル</uri:title> <uri:keyword>ポータルサイト</uri:keyword> <uri:keyword>ぐーぐる</uri:keyword> </uri:site> <uri:site xmlns:uri="http://www.msn.co.jp/"> <uri:title>MSN</uri:title> <uri:keyword>portal</uri:keyword> <uri:keyword>エムエスエヌ</uri:keyword> </uri:site> </sites> ------------ 例えば、フォームから「ポータルサイト」というキーワードを受け取ったときに、「キーワード」と言う<uri:keyword>を持っているノードと同じ名前空間URIをもつ<uri:title>の要素(この場合、「ヤフー」と「ぐーぐる」)を取り出したいのです。簡単に言えば、「キーワード」を参照して「タイトル」を得たいのです。

関連するQ&A

  • SimpleXML関数で取得したXML要素を逆順にしたい

    SimpleXML関数で取得したXML要素を逆順にしたい お世話になります。 phpのsimplexml関数で取得したXML要素を 逆順にして表示させるにはどうしたらよいでしょうか? 通常、RSSなどを読み込み表示させた場合、新しいものから並ぶと思いますが、 これを逆順で古いほうから並ばせたいです。 rsortやarray_reverseを使ってみましたが、うまくいきませんでした。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • simplexmlでルート要素の値を取得したい

    PHPでsimplexmlを用いていますが、XMLから値を取得する方法で、他のタグなどの情報は取り出せるのですが、ルート要素である以下の文章からtotalResultsの値である20だけを取り出したいですがうまくいきません。 <ResultSet totalResults="20" totalReturned="2"> 以下のようにあるところへ投げた結果のXMLを取得しています。 $file = file_get_contents( $url ); $xml = simplexml_load_string( $file ); お手数ですがよろしくお願いします。

    • ベストアンサー
    • PHP
  • PHP5 domDocumentで簡単に深いノードを取得する。但し、SimpleXMLを使わない

    環境はPHP5です。 SimpleXML(simplexml_load_file)を使わない事情がありまして、domDocumentを使っています。 $dom = new domDocument(); $dom->load("example.xml"); $root = $dom->documentElement; foreach($root->childNodes as $elems) { if ($elems->nodeType == XML_ELEMENT_NODE && $elems->nodeName == "Items") { ... ... ... 例えば以下のようなXMLの場合、<D2>のyyyyyを取得する為に上のプログラムだと、 foreach, ifのネストが深くなり、階層が深くなるにつれてプログラムの記述も増えて 非常に面倒ですが、$rootを使って、yyyyyの値を1行程度で取得する方法ないのでしょうか? <A> <Items> <B1></B1> <B2> <C> <D1>xxxxx</D1> <D2>yyyyy</D2> </C> </B2> <B3></B3> </Items> </A>

    • ベストアンサー
    • PHP
  • XMLの要素の内容の中に要素

    VisualBasic6.0にて、XMLを作成するプログラムを作っています。 XMLの作成、編集はMSXMLを使用しており、編集保存はできたのですが、下記のような要素の出力の仕方がわかりません。 <Node1>  あいうえお  <Node1-1>abcde</Node1-1>  かきくけこ </Node1> このように要素の文字列の途中に子要素を作成したいです。 「Node1」要素に、子要素「Node1-1」を追加するサンプルです。 Cドライブ直下に以下の内容のXMLファイル「test.xml」を作成 <?xml version="1.0" encoding="shift_jis"?> <Node1> </Node1> VB6にて、参照設定に「Microsoft XML V6.0」を追加し以下のコードを作成。 Private Sub Command1_Click() Dim xDoc As MSXML2.DOMDocument Set xDoc = New MSXML2.DOMDocument Dim node As IXMLDOMNodeList Dim Addnode As IXMLDOMNode Dim obj As IXMLDOMNode If xDoc.Load("C:\test.xml") Then Set node = xDoc.documentElement.selectNodes("/Node1") For Each obj In node Set Addnode = obj.appendChild(xDoc.createNode(NODE_ELEMENT, "Node1-1", "")) Addnode.Text = "abcde" Next xDoc.save ("C:\test.xml") End If Set xDoc = Nothing End Sub

  • xmlの値を配列に格納したいんですけどエラーがでてしまう。

    <?xml version="1.0" encoding="UTF-8" ?> <Dataroot> <aaa> <bbb> <ccc>値1</ccc> </bbb> <bbb> <ccc>値2</ccc> </bbb> </aaa> </Dataroot> ---------------------------------------------------------------- のようなXML文書がある時<ccc></ccc>の値を取り出す場合 ---------------------------------------------------------------- Imports System Imports System.IO Imports System.Xml public class Sample public shared sub Main() Dim doc as XmlDocument = new XmlDocument() doc.Load("data.xml") 'XML文書の読み込み Dim root as XmlElement = doc.DocumentElement Dim nodeList as XmlNodeList nodeList = root.SelectNodes("/Dataroot/aaa/bbb")'/cccまでやる方が簡単 Dim node as XmlNode Dim ccclist() As String = Nothing for each node in nodeList ccclist(nodeList.Count) = node.SelectSingleNode("ccc").InnerText '内容の取り出し next end sub end class としているのですが ccclist(nodeList.Count) = node.SelectSingleNode("ccc").InnerText '内容の取り出し この行で オブジェクト参照がオブジェクト インスタンスに設定されていません。 とエラーがでて困っています。 これはどのように修正すればよろしいでしょうか? 教えてください。お願いします。

  • phpでxmlが動かない macOsXLion

    phpでxmlの練習をしてるんですが全く動作しません。なんででしょうか? コードを次に書きます。 <?php $doc = new DOMDocument; // DOMDocumentのインスタンス生成 $root = $doc->createElement("cars");  // root要素を作成する $doc->appendChild($root); // docの子としてrootを追加する $elm1 = $doc->createElement("car"); // car要素を作成する $root->appendChild($elm1); // car要素をrootの子として追加する $txt1 = $doc->createTextNode("スポーツカー"); // テキストノードを作成する $elm1->appendChild($txt1); // テキストノードをテキスト要素としてelm1の子として追加する $elm2 = $doc->createElement("car"); // car要素を作成する $root->appendChild($elm2); // rootの子としてcar要素を追加する $txt2 = $doc->createTextNode("トラック"); // テキストノードを作成する $elm2->appendChild(txt2); // elm2にtxt2を追加する print $doc->saveXML(); ?> よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHP4でのXMLデータの取り扱い

    Webサービスを利用してXMLデータを取得するスクリプトをPHPで書いています。レンタルサーバの関係でバージョンは4.4.4しか使えません。 XMLを扱う関数というと、PHP5ではsimpleXMLやXMLReaderなどがあるようで、各要素へアクセスするにも $xml=simplexml_load_file('books.xml'); foreach($xml->book as $book){ .... という感じでオブジェクトとしてアクセスできるようですが、こういうのをPHP4で実現する方法はないのでしょうか?例えば入れ子になったデータだと、深い階層にたどりつくために foreach($results as $key => $value){ foreach($value $key2 => $value2){ foreach($value $key3 => $value3){ ... } } } みたいな感じで書いているのですが、まったくスマートではないですし、なにか間違っているような気がします。良い方法があればお教えください。よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • PHPでXMLから正規表現で特定の要素を抜き出しているんですが‥。

    このようなXMLがあったとします。 sample.xml ---------------------------- <rss> <xml> <title>タイトル</title> <link>ttp://xxx.jp/</link> </xml> </rss> ---------------------------- ここから <xml> ~ </xml> の部分だけを抜き出すのですが、 $data = file_get_contents("sample.xml"); preg_match_all("|<xml>((?:(?!</xml>).)*)</xml>|si", $data, $matchs); で、$matchs[1] の中に <xml> ~ </xml> の部分が配列で入っています。 この『((?:(?!</xml>).)*)』の部分の意味がよく分かりません。 これは先輩から教えてもらった構文ですが、先輩に聞いても詳しい意味を知らないそうです。 『? ! . *』の意味は理解しているけど『:』は参考書でもよく分かりませんでした。 ネットを少し検索したけどこの取得構文の解説が見つからないため質問します。 simpleXML のようなクラスを使わずに、他にも正規表現で XML から要素を取得できる簡単な方法をご存知の方がいましたらどうか教えてください。 急ぎではありませんのでよろしくお願いします。

    • ベストアンサー
    • PHP
  • SimpleXMLでxmlのデータを修正するときの疑問

    PHP5でflashで扱うXMLの編集をしています。 <xml> <aaa>12345</aaa> </xml> というxmlに対し、 $nodeName = "aaa"; $xml = simplexml_load_file($xmlFile); $xml->$nodeName->title = "aiueo"; という感じで、xmlの更新をしていますが、 <xml> <aaa>12345</aaa> <aaa>67890</aaa> <aaa>24680</aaa> </xml> と、xmlのnodeが同名複数になったとき、 $xml->aaa[0]->title = "aiueo"; 相当のことを、ノード名も、何番目のノードかも、 変数をつかって実行する方法はありますか? 当然のごとく、 $nodeName[$num]は、$nodeNameの配列の値とみなされますし、 $a = $nodeName . '[' . $num . ']'; $xsml->$a->title = "aiueo"; とやると、"aaa[0]"という文字列をノード名にしてデータ追加してしまいます。 ご存知の方がいらっしゃいましたら、ご教示下さい。

    • 締切済み
    • PHP
  • PHP5 XML クエリ 

    PHP5でXMLのテストをしているのですが、わからないことがあります。 --- test.xml <A> <B> <C>TEST</C> <D> <E>1</E> <F>2</F> <G>3</G> </D> </B> </A> <?php $doc = new DOMDocument; $doc->preserveWhiteSpace = false; $doc->Load('test.xml'); $xpath = new DOMXPath($doc); $query = '//A/B/D/E'; $entries = $xpath->query($query); foreach ($entries as $entry) { echo "$entry->nodeValue\n"; } で1が返されますが、 $query = '//A/B/D/E'; で、Eのノードを決め打ちしているので、foreachで回すのが気に入らないのですが この方法が一般的でしょうか? $e = なんとか??; で$entries = $xpath->query($query); のあと、取得できないでしょうか? あと、クエリという使い方で例えば2以上データを取得する この場合はF,Gの要素を取得するクエリの記述方法が知りたいです。

    • ベストアンサー
    • PHP

専門家に質問してみよう