- ベストアンサー
XMLの値の取得方法について
- XMLの値の取得方法について説明します。
- 車種のIDや価格、燃費の値を取得する方法がうまくいかないようです。
- プルダウンでメーカを選択し、選択された車種の価格と燃費を表示する機能を実装したいと考えています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 クロスブラウザまで考えていなかったので私が提示したものはIEで動きませんでした。 一応、IEとFirefoxで動かして、同じ動きになるようにしたソースをフルで提示します。 動作内容はできる限りコメントに書きました。 動作を追いながら、自分で作ったものと比較、どういった処理をしているか見てみてください。 わからないところがあったらまた質問してください。 (突貫で作っておりもっといい作りがあるかもしれませんので参考までにどうぞ) <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>サンプル</title> <script> function loadXML() { var url = './xml.xml?'+(new Date).getTime(); var xmlHttp; try { xhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { xhttp = new XMLHttpRequest(); } xhttp.open ( "GET", url, false ); xhttp.send ( null ); return xhttp.responseXML; } // メーカーごとのCar情報を保持するオブジェクト var makers = {}; // メーカープルダウン用の変数 var selMaker; // 車種プルダウン用の変数 var selCar; function loadData() { // メーカープルダウンを取得 selMaker = document.getElementById('sel-maker'); // 車種プルダウンを取得 selCar = document.getElementById('sel-car'); // xmlをロード var xmlDocs = loadXML(); // メーカータグの要素を取得 var xmlAttr = xmlDocs.getElementsByTagName( 'メーカー' ); // メーカータグ分のループ処理 for ( var i = 0; i < xmlAttr.length; i ++ ) { // i番目のidを取得する var maker = xmlAttr[i].getAttributeNode('id').value; // メーカープルダウンのoptionタグを動的に生成 selMaker.options[i+1] = new Option ( maker , maker ); // i番目のメーカータグ内の車種タグを取得する var kind = xmlAttr[i].getElementsByTagName('車種'); // 車種情報の配列を宣言 var cars = new Array(); // 車種タグ分のループ処理 for ( var j = 0; j < kind.length; j ++ ) { // 価格の値を取得 var kakaku = kind[j].getElementsByTagName('価格')[0].firstChild.nodeValue; // 燃費の値を取得 var nenpi = kind[j].getElementsByTagName('燃費')[0].firstChild.nodeValue; // Carオブジェクトを生成 var obj = new Car ( kind[j].getAttributeNode('id').value, kakaku, nenpi ); // Carオブジェクトを配列に追加 cars.push ( obj ); } // メーカー配列にname=idと,メーカーに紐付くCarオブジェクトをcarsとして追加 makers[maker] = { name: maker, cars: cars }; } } /** * ページロード後に実行する処理 */ window.onload = function() { // xmlを解析しデータを生成する loadData(); /** * メーカープルダウンを変更した際に実行する処理 */ selMaker.onchange = function() { // 車種プルダウンをクリア selCar.options.length = 0; // 先頭に”車を選択”を追加 selCar.options[0] = new Option ( '車を選択', '' ); // 変更した際に先頭の”メーカーを選択”を選択した際は // 価格、燃費の表示を”-”とし、処理を中止 if ( this.value === '' ) { setData ( '-', '-' ); return; } // メーカーが選択された場合はidが取得できるのでその文字列を利用して // メーカー配列から情報を取得する var maker1 = makers[this.value]; // 取得した情報の中にcarsという配列があるのでその数分のループ処理 for ( var i = 0; i < maker1.cars.length; i ++ ) { // 先頭には”車を選択”があるので次のindexから(i+1)optionを追加する selCar.options[i+1] = new Option ( maker1.cars[i].name, maker1.cars[i].name ); } }; /** * 車種プルダウンを変更した際に実行する処理 */ selCar.onchange = function() { // 先頭にある”車を選択”が選択された場合は // 価格、燃費の表示を”-”とする if ( this.value === '' ) setData ( '-', '-' ); // メーカー配列から情報を取得する var maker = makers[selMaker.value]; // 取得した情報の中にcarsという配列があるのでその数分のループ処理 for ( var i = 0; i < maker.cars.length; i ++ ) { // ループ処理している間に選択された車種と一致した場合に // 価格、燃費の表示を変更する if ( maker.cars[i].name === this.value ) { setData ( maker.cars[i].kakaku, maker.cars[i].nenpi ); } } } } /** * Carオブジェクト * 車種、価格、燃費を持つ */ function Car ( name, kakaku, nenpi ) { this.name = name; this.kakaku = kakaku; this.nenpi = nenpi; } /** * 価格と燃費の表示を更新する */ function setData ( kakaku, nenpi ) { document.getElementById('txt-kakaku').innerHTML = kakaku; document.getElementById('txt-nenpi').innerHTML = nenpi; } </script> </head> <body> <select id="sel-maker"> <option value="">メーカーを選択</option> </select> <select id="sel-car"> <option value="">車を選択</option> </select> <hr /> <dl> <dt>価格</dt> <dd><span id="txt-kakaku">-</span></dd> <dt>燃費</dt> <dd><span id="txt-nenpi">-</span></dd> </dl> </body> </html>
その他の回答 (3)
- LancerVII
- ベストアンサー率51% (1060/2054)
こんにちは。 >selMaker.options[i+1] = new Option ( maker , maker ); エラーの部分がはプルダウンへ動的にoptionタグを追加しているところです。 (すみません、ソースを載せる際に残っていたようです) >また、具体的なプルダウンへ、あてたコードも見ることもできれば助かるのですが。 #1さんへの補足で >かもしれないのですが、javascriptで実現したいと考えています。 >XSLT は 難しくて...。 とあったのでJavaScriptは出来ると思ったので複雑かな?と思うxmlの解析部分だけ載せました。 var selMaker = document.getElementById('sel-maker'); と定義してHTMLに <select id="sel-maker"></select> を定義すればメーカーのプルダウンが生成されます。 あとはやってみて、わからなかったら再度質問してください。 (メーカーのプルダウンは上記で生成されます。次の車種プルダウンはそれの応用です)
- LancerVII
- ベストアンサー率51% (1060/2054)
こんにちは。 転記ミスかもしれませんが”メーカー”とメーカが混在しておりxmlとしてまずいです。 多分以下のようなxmlだと思いますが如何でしょうか。 makersは以下のような感じで値が入ります。 makers['honda'].cars[0].name; // fit makers['honda'].cars[0].nenpi; // 50km makers['toyota'].cars[1].name; // sai makers['toyota'].cars[1].kakaku; // 40km あとはこのmakersの情報を利用してプルダウンの生成等を行えば良いです。 === xml <?xml version="1.0" encoding="UTF-8"?> <価格> <メーカー id="toyota"> <車種 id="wish"> <価格>200万</価格> <燃費>30km</燃費> </車種> <車種 id="sai"> <価格>250万</価格> <燃費>40km</燃費> </車種> </メーカー> <メーカー id="honda"> <車種 id="fit"> <価格>159万円</価格> <燃費>50km</燃費> </車種> <車種 id="crz"> <価格>236.5万円</価格> <燃費>40km</燃費> </車種> </メーカー> </価格> ==== JavaScript var makers = {}; function setData() { var xmlDocs = loadXML();//xml読み込み var xmlAttr = xmlDocs.getElementsByTagName( 'メーカー' ); // ”メーカー”のタグの数分のループ処理 for ( var i = 0; i < xmlAttr.length; i ++ ) { var maker = xmlAttr[i].getAttributeNode('id').value; // ”メーカー”のidを取得 selMaker.options[i+1] = new Option ( maker , maker ); // i番目の”メーカー”タグ内の車種タグを取得 var kind = xmlAttr[i].getElementsByTagName('車種'); // carオブジェクトの配列を宣言 var cars = new Array(); // ”車種”のタグの数分のループ処理 for ( var j = 0; j < kind.length; j ++ ) { // j番目の”車種”タグの中の”価格”を取得 var kakaku = kind[j].getElementsByTagName('価格')[0].textContent; // j番目の”車種”タグの中の”燃費”を取得 var nenpi = kind[j].getElementsByTagName('燃費')[0].textContent; // carオブジェクトを生成(車種id,価格,燃費) var obj = new Car ( kind[j].getAttributeNode('id').value, kakaku, nenpi ); // 生成したcarオブジェクトを配列に追加 cars.push ( obj ); } // makersにidを利用して配列を生成し、メーカーごとのcarオブジェクトを格納する makers[maker] = { name: maker, cars: cars }; } } // carオブジェクト function Car ( name, kakaku, nenpi ) { this.name = name; this.kakaku = kakaku; this.nenpi = nenpi; }
補足
コードを書いていただきありがとうございます。とてもうれしいいです。 以下のラインが、よくわからなかったのと、この行で script が止まるようです。 selMaker.options[i+1] = new Option ( maker , maker ); また、具体的なプルダウンへ、あてたコードも見ることもできれば助かるのですが。
- ORUKA1951
- ベストアンサー率45% (5062/11036)
XSLTを使うほうが早いのでは??
補足
かもしれないのですが、javascriptで実現したいと考えています。 XSLT は 難しくて...。
補足
ご返答いただきありがとうございます。頼ってしまいすみません。 XMLは変更せず以下のようにHTMLを記述しました。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> </head> <body> <select id="sel-maker"></select> <script> setData(); function readXML() { if ( window.XMLHttpRequest ) { // code for IE7+, Firefox, Chrome, Opera, Safari. xmlhttp=new XMLHttpRequest(); } else { // code for IE6 bellow. xmlhttp = new ActiveXObject( 'Microsoft.XMLHTTP' ); } xmlhttp.open( 'GET', './test.xml', false ); xmlhttp.send(); xmlDocs = xmlhttp.responseXML; return xmlDocs; } var makers = {}; function setData() { var xmlDocs = readXML(); var xmlAttr = xmlDocs.getElementsByTagName( 'メーカー' ); for ( var i = 0; i < xmlAttr.length; i ++ ) { var maker = xmlAttr[i].getAttributeNode('id').value; var selMaker = document.getElementById('sel-maker'); selMaker.options[i+1] = new Option ( maker , maker ); var kind = xmlAttr[i].getElementsByTagName('車種'); var cars = new Array(); for ( var j = 0; j < kind.length; j ++ ) { var kakaku = kind[j].getElementsByTagName('価格')[0].textContent; var nenpi = kind[j].getElementsByTagName('燃費')[0].textContent; var obj = new Car ( kind[j].getAttributeNode('id').value, kakaku, nenpi ); cars.push ( obj ); } makers[maker] = { name: maker, cars: cars }; } } // carオブジェクト function Car ( name, kakaku, nenpi ) { this.name = name; this.kakaku = kakaku; this.nenpi = nenpi; } </script> </body> </html> loadXML()に関しては、検索等しましたが、使い方がわからず、 readXML()と自作しました。 どうしても、以下の行でスクリプトが止まります。 makers[maker] = { name: maker, cars: cars }; >>(メーカーのプルダウンは上記で生成されます。次の車種プルダウンはそれの応用です) 車種プルダウンも難解で作成できませんでした。