• ベストアンサー

JQueryでXML検索

お世話になります。 blue-horse と申します。 JQueryでXML文書の検索・抽出を行おうとしています。 が、フィルタが上手く行きません。 どこがどうおかしいのでしょうか。 ご教示ください。 参考になるサイト等も教えて頂ければありがたいです。 [XML例] <?xml version='1.0' encoding='UTF-8'?> <xml_recordset>   <record>     <field_A>北海道</field_A>     <field_B>北海道</field_B>     <field_C>札幌市</field_C>   </record>   <record>     <field_A>青森</field_A>     <field_B>東北</field_B>     <field_C>青森市</field_C>   </record>   <record>     <field_A>秋田</field_A>     <field_B>東北</field_B>     <field_C>秋田市</field_C>   </record>   <record>     <field_A>岩手</field_A>     <field_B>東北</field_B>     <field_C>盛岡市</field_C>   </record>   <record>     <field_A>山形</field_A>     <field_B>東北</field_B>     <field_C>山形市</field_C>   </record>   <record>     <field_A>宮城</field_A>     <field_B>東北</field_B>     <field_C>仙台市</field_C>   </record>   <record>     <field_A>福島</field_A>     <field_B>東北</field_B>     <field_C>福島市</field_C>   </record> </xml_recordset> [JavaScript] // JQueryは読み込み済みです var my_xml = get_xml(); //自作関数,XMLを取得,動作確認済み $my_record = $(my_xml).find("field_B"); alert($my_record.length); //成功,7が表示されます $tohoku = $(my_xml).find("field_B:contains('東北')"); alert($tohoku.length); //失敗,何も表示されません(6が表示されることを期待)

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

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

> alert('my_doc: ' + xml.documentElement.childNodes.length); > // 14が表示されます(正常:15) Node には、Element のほか、空白や、改行(TextNode)も含まれるので、14, 15 という数は、<record> の数+空白,改行 の数です。 で、IE と Firefox その他では、空白や改行のカウントの仕方が異なるので、数字の違いはそのためです。それほど問題になるところではないので、あまり気にしなくていいと思います。どうしても気になる場合は、IE 独自の childlen を使うか、xml に空白や改行を書かないようにするかになると思います。 >alert('my_record.field_B LIKE "%東北%": ' + tohoku.length); >// 0が表示されます(正常: 6) jQuery の不具合っぽいですね。 jQuery のソースファイルの 1940 行目辺りを下のように変更してみてください。  filter: {   PSEUDO: function(elem, match, i, array){    var name = match[1], filter = Expr.filters[ name ];    if ( filter ) {     return filter( elem, i, match, array );    } else if ( name === "contains" ) {     /* 変更 */     var textContent = elem.textContent || elem.innerText;         if( 'string' != typeof textContent ) textContent = Expr.filter.getTextContent( elem );         return (textContent || "").indexOf(match[3]) >= 0;     /* 変更 */    } else if ( name === "not" ) {     var not = match[3];     for ( var i = 0, l = not.length; i < l; i++ ) {      if ( not[i] === elem ) {       return false;      }     }     return true;    }   },      /* 追加 */   getTextContent : function( n, b ) {    return n ? ( n.nodeType == 3 ? n.nodeValue : '' ) + arguments.callee( n.firstChild, 1 ) + ( b ? arguments.callee( n.nextSibling, 1 ) : '' ) : '';   },   /* 追加 */

blue-horse
質問者

お礼

yuu_x 様: 回答ありがとうございます。 望んでいた結果を得ることが出来ました。 ありがとうございます。 JQueryのコードに手を入れると言う発想は全くありませんでした。 (知識・技術的に、まだとてもその域にはありませんので。) 具体的な修正箇所と内容まで提示頂けたので、解決に至ることが出来ました。 重ねてお礼申し上げます。 ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • x_jouet_x
  • ベストアンサー率68% (162/236)
回答No.2

まずblue-horseさんのJavaScriptについてですが、 var $my_recordX = $(my_doc).find("field_B"); と記述されているところを var my_recordX = $(my_doc).find("field_B"); として下さい。変数名の先頭に "$" をつけるとjQueryにどのような影響を与えるか分かりませんが、一応指摘しておきます。 またJavaScript全体を見たところ、XHR通信を利用してXMLデータを取得していますよね。 XHR通信を利用されるのであれば、jQueryのajax()関数を使用されてはいかがですか? IEのみのサポートということですが、ajax()関数を使用すればクロスブラウザに関しても意識しなくて済みますので・・・。 それらをふまえて、blue-horseさんが期待されるJavaScriptのソースコードは以下のようになります。 [JavaScript] /* * Ajax通信成功時の処理 */ var handleSuccess = function(xml, dataType) { alert('my_doc: ' + xml.documentElement.childNodes.length); // 15が表示されます var field_B = $(xml).find("field_B"); alert('my_doc.field_B: ' + field_B.length); // 7が表示されます var tohoku = $(xml).find("field_B:contains('東北')"); alert('my_record.field_B LIKE "%東北%": ' + tohoku.length); // 6が表示されます } /* * Ajax通信失敗時の処理 */ var handleError = function(XMLHttpRequest, textStatus, errorThrown) { } /* * ボタン押下時の処理 */ function xhr(success) { // Ajax通信 new $.ajax({ url: "sample.xml", type: "GET", dataType: "xml", success: handleSuccess, error: handleError }); } もしも動作するものがご覧になりたければ、 http://ajax-world.sakura.ne.jp/jquery/test/sample.html をご覧下さい。私が作成したものです。

blue-horse
質問者

お礼

x_jouet_x 様: 回答ありがとうございます。 >変数名の先頭に "$" をつけるとjQueryにどのような影響を与えるか分かりませんが、一応指摘しておきます。 基本的な勉強をすっ飛ばして、いきなりコーディングに入っているので、問題のある箇所が散見されると思います。 ご指摘ありがとうございます。 提示頂いたサンプルコードを実行してみました。 FirefoxとChromeでは正常動作するのですが、IE6,IE8,では、何故か正しく実行されませんでした。 以下、IE6,IE8,実行結果 alert('my_doc: ' + xml.documentElement.childNodes.length); // 14が表示されます(正常:15) alert('my_doc.field_B: ' + field_B.length); // 7が表示されます(正常: 7)問題なし。 alert('my_record.field_B LIKE "%東北%": ' + tohoku.length); // 0が表示されます(正常: 6) が、正常動作するお手本を頂けたので、しっかりした足場が出来ました。 提示頂いたコードを元に、もう少し頑張ってみます。 ありがとうございます。

すると、全ての回答が全文表示されます。
  • x_jouet_x
  • ベストアンサー率68% (162/236)
回答No.1

blue-horseさんのJavaScriptですが、以下のような私の環境では動作しました(確認済み)。 ・jQuery … Ver.1.3.2 ・JavaScriptの文字コード … UTF-8 ・ブラウザ … Fedora 3.0.4 もし宜しければ、使用されているjQueryのバージョンと記述されたJavaScript(HTML)の文字コードを教えて頂けないでしょうか?

blue-horse
質問者

お礼

x_jouet_x 様: 回答ありがとうございます。 お礼遅くなりまして申し訳ございません。 JQueryのバージョンと、JavaScript、HTMLの文字コードは以下になります。 JQuery バージョン:  jQuery JavaScript Library v1.3.2 JavaScript 文字コード:  UTF-8 HTML 文字コード  ファイル:UTF-8  charset :UTF-8 ブラウザ:  Internet Explorer 6  Internet Explorer 8 です。 気になりましたので、他のブラウザでも試してみました。 結果 Firefox 3.0.6:  alert($my_record.length); に期待する「7」すら表示されず。  alert($tohoku.length); の結果はIEと同様に全く表示されず。 Chrome 1.0.154.65:  alert($my_record.length); の結果が「15」と表示される。  alert($tohoku.length); の結果はIEと同様に全く表示されず。 ブラウザによっても結構な差が出るものなのですね。 幸い、クロスブラウザ仕様については、IE6,IE7,IE8をサポートすれば良い状況です。 その他、不足している情報等ございましたらご指摘下さい。 以上、失礼いたします。

blue-horse
質問者

補足

すみません。 最初に掲示したコードと結果に間違いがありました。 「7」が表示されるコードはalert($my_record.length); ではありません。 他のブラウザでの結果についての記述も同様です。 正) var my_doc = my_xml.documentElement; alert('my_doc:' + my_xml.documentElement.childNodes.length); //成功,「7」が表示されます。 誤) var $my_record = $(my_xml).find("field_B"); alert($my_record.length); //成功,7が表示されます ↑失敗,何も表示されません。 以下、修正版コード全体です。 申し訳ございません。 // XMLHttpRequestオブジェクト生成 function get_XhrObject() {   var xhr_object;   if ( window.XMLHttpRequest )   {     try     {       xhr_object = new XMLHttpRequest();     }     catch ( e )     {       xht_object = false;     }   }   else if ( window.ActiveXObject )   {     try     {       xhr_object = new ActiveXObject("Msxml2.XMLHTTP");     }     catch ( e )     {       try       {         xhr_object = new ActiveXObject("Microsoft.XMLHTTP");       }       catch ( e )       {         xhr_object = false;       }     }   }   return xhr_object; }; // XMLデータ受取 function get_XML(url) {   var xml = null;   var xhr = get_XhrObject();     xhr.open("GET", url, false); // xhr.setRequestHeader("If-Modified-Since", "01 Jan 2000 00:00:00 GMT");     xhr.onreadystatechange = function()     {       if ( (xhr.readyState == 4) && (xhr.status == 200) )       {         xml = xhr.responseXML;       }     }     xhr.send(null);   return xml; }; var url = 'sample.xml'; var my_xml = get_XML(url); var my_doc = my_xml.documentElement; alert('my_doc:' + my_xml.documentElement.childNodes.length); //成功,7が表示されます var $my_recordX = $(my_doc).find("field_B"); alert('my_doc.field_B:' + $my_recordX.length); //失敗,何も表示されません(7が表示されることを期待) var $my_record = $(my_xml).find("field_B"); alert('my_record.field_B:' + $my_record.length); //失敗,何も表示されません(7が表示されることを期待) var $tohoku = $(my_xml).find("field_B:contains('東北')"); alert('my_record.field_B LIKE "%東北%":' + $tohoku.length); //失敗,何も表示されません(6が表示されることを期待)

すると、全ての回答が全文表示されます。

関連するQ&A