• ベストアンサー

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

  • XML型に対する問い合わせ

    以下のような(1)と(2)のxml型を値を持つレコードがある場合にbの中でcとdが両方1の場合だけ検索((1)のレコードだけが欲しい)するようにはどのように問い合わせればば良いでしょうか? (1) <a>    <b><c>1</c><d>1</d></b>   </a> (2) <a>    <b><c>1</c><d>0</d></b>    <b><c>0</c><d>1</d></b>   </a> 自分で考えた問い合わせだと(1)と(2)の両方のレコードが返ってきてしまいます。 select * from test where   '1'=ANY(xpath('/a/b/c/text()',xml)::text[])   AND '1'=ANY(xpath('/a/b/d/text()',xml)::text[])

  • 複数のxmlを同ページに読み込みたい

    同じ項目をもつxmlをカテゴリ別に複数作成された状態で、同一html上にjqueryで読み込みたいです。 var xmlFiles=new Array("a.xml","b.xml","c.xml"); $(document).ready(function(){ for(var i=0;i<xmlFiles.length;i++){ $.ajax({url: '',type: 'GET', dataType: 'xml',timeout: 100000,error: function(){alert('xmlファイルの読み込みに失敗しました');}, success: function(xml){ 処理 } }); } }); これだとおかしくなってしまいます。 $.ajax~~を読み込み名を変えて繰り返し記述してもうまくいかないのですが、これは1つのxmlにするしかないのでしょうか。

  • XMLからXML

    こんにちわ。 以下のやり方がわからなく、困っています。 XSLTを使って以下のようなXML→XMLを行いたいのですが。 変更前: <a> <b> <c>abc</c> <d>def</d> </b> </a> 変更後: <b> <c>abc</c> <d>def</d> </b> ようするに、指定したタグ以下のXML構造をそのまま取り出したいのです。 <xsl:template match="/a"> <xsl:apply-templates select="b"/> </xsl:template> だと中身のabc defしか取れません。 <c>とか<d>は、時によって変わる場合、どのようなXSLT を書けばよいのでしょうか? 申し訳ありませんが、わかる方がいれば教えてください。

    • 締切済み
    • XML
  • XMLとかで出来ますか?

    XMLもXSLもXSLTも何も知らないので出来るのかわかりませんが。 Aに1・2という情報?属性?を付けて Bに2・3を付けて Cに1を付けて 1が付いているのはA・C 2が付いているのはA・B 3が付いているのはB というように表示するにはどうすればいいでしょう?

    • 締切済み
    • XML
  • 既存のXMLを別のXMLの要素として追加する方法

    JavaでDOMを使用して、既に作成してあるXMLを別のXMLの要素として追加しようと思っているのですが、なかなか上手くいかないので投稿いたしました。 具体的に以下のような既存のXMLファイルがあると仮定して、 <?xml version="1.0" encoding="UTF-8"?> <a> <b>0</b> <c>1</c> <d>2</d> </a> 上記のXMLの親ノード(逆に言えば、このXMLの子ノードとして上記XMLを追加)にあたるXMLは以下のようになっています。 <?xml version="1.0" encoding="UTF-8"?> <A> </A> そして<A>と</A>の間に既存のXMLを追加して、 <?xml version="1.0" encoding="UTF-8"?> <A> <a> <b>0</b> <c>1</c> <d>2</d> </a> </A> のようにしたいと考えています。 よろしくお願いします。

    • ベストアンサー
    • Java
  • PHPでXMLを扱いたいのですが

    PHPでXMLを扱いたいのですが、わからないところがあります。 <XML>  <T>   <A>    <a>    </a>    <b>    </b>    <c>     <c1></c1>     <c2></c2>    </c>   </A>   <A>    <a>    </a>    <b>    </b>    <c>     <c1></c1>     <c2></c2>    </c>   </A>   <A> 以下くりかし・・・  </T> </XML> このような感じのXMLがある時に、<a>,<b>等のタグの中身はちゃんと一つめの<A>、二つめの<A>、のように、 繰り返しある全てを取り出すことが来るのですが、 <c1>のようにもう一つ奥になっているものが取り出せません。 //以下成功するソースです。 foreach(XML->T->A as $value){ $data[]=$value->a; } for($i=0,$n=count($data);$i<$n;$i++){ $file=$data[$i]; } echo $file; これだとうまく動作しますが、 //以下失敗するソースです。 foreach(XML->T->A->c as $value){ $data[]=$value->c1; } for($i=0,$n=count($data);$i<$n;$i++){ $file=$data[$i]; } echo $file; このように<c1>を取り出そうとすると、繰り返しある<c1>の内の初めの一つしか取りだせません。 もう何回も色々と変えてやっているのですが、どれもうまくいきませんでした。 どうすればいいのでしょうか。分かる方教えて下さい、お願いします。

    • 締切済み
    • PHP
  • アクセス帳票フォームのループ処理ができない

    いつもお世話になっています。 win7,Access2010 です。 帳票フォーム上にいくつかの連結フィールドがあり、A,B,Cとします。 Aには初期値が入力されています。 Bに1レコードづつ値を入力し、すべてのレコードに入力し終わった後に、 全レコードにおいて、A-Bの値をCに代入したいのです。 以下のようなコードを書きましたが、 カレントフィールドにのみ適用されます。 一括で全レコードに適用するためには、 どうすればいいのでしょうか? よろしくお願いします。 Private Sub コマンド71_Click() Dim rs As Recordset Set rs = Me.Recordset.Clone rs.MoveFirst Do Until rs.EOF Me!C = A - B rs.MoveNext Loop rs.Close MsgBox "計算が終了しました" End Sub

  • XML::Simple

    xmlファイルの中の<service>aa001</service>のaa001の値が 取得できません。 <service>のセクションが複数行あるとうまくデータの取得可能ですが。 複数または一行の<service>からのデータ取得できないのでしょうか? **************************************************** use XML::Simple; my $root = XMLin(".\\test.xml"); #test.xml---------------------------------------- #<?xml version="1.0" encoding="utf-8" ?> #<root> #<server no ="1"> # <MMM>0000000001</MMM> # <service>aa001</service> # <WWW>a001</WWW> # <WWW>b001</WWW> #</server> #<server no ="2"> # <MMM>0000000002</MMM> # <service>aa002</service> # <service>bb002</service> # <service>cc002</service> # <WWW>a002</WWW> # <WWW>b002</WWW> #</server> #</root> #---------------------------------------- for my $Serv (@{$root->{'server'}}){ foreach my $Service (@{$Serv->{'service'}}){ print "$Service\n"; } }

    • ベストアンサー
    • Perl
  • jQueryでxmlの異なるタグ要素を取得したい。

    jQueryを最近勉強したての者です。 詳しい方、どうか教えて下さい。 HTMLにxmlのデータを読み込ませようとしています。 概略をお話しすると、 htmlファイルによって、xmlの別々の要素を取得したいのです。 やりたいメソッドは同じです。 別々の要素の中のデータによって、imgの表示/非表示を切り替えたいのです。 問題は、対象となるhtmlファイルが複数あり そのhtmlファイルによって、参照するxmlのタグが異なる事なんです。 xmlは、以下のように<shopdata>をルートノードとし、以下のような感じです。 --------------------- <?xml version="1.0" encoding="utf-8"?> <shopdata> <item> <name1>0</name1> <name2>1</name2> <name3>0</name3> </item> </shopdata> --------------------- <name*>~</name*> の中のデータは、0もしくは1なのですが 0の時はimgを表示 1の時はimgを非表示させようと考えています。 ただ<name1><name2><name3> とタグ名がバラバラなんです。 ※おしりの数字が違うだけで、規則的ではあります。 ちなみにhtmlは複数あって  a.htmlの時は→xmlの<name1>を参照  b.htmlの時は→xmlの<name2>を参照  c.htmlの時は→xmlの<name3>を参照 という感じです。 ※htmlファイル名は特に規則的ではなく、いろいろなファイル名がついています。。。 最初、考えたのは、 htmlのどこかに、id="1"と入れて、idが1の時は、<name1>の要素を取得し、 htmlのどこかに、id="2"と入れて、idが2の時は、<name2>の要素を取得し… っていうことを考えたのですが、それもどのように書いたら良いのかが分からないんです。 そもそも、そういった事は可能なのでしょうか? ちなみのhtmlのbodyタグ自体がテンプレートでできているので、 idをどこかにふるとしたら、head内とかになるのしょうか? それぞれ、ボタンの表示は、 if文を使って、show(),hide()メソッドを使うとは思うのですが… 詳しくコードを教えていただけたら、助かります。 どうか、宜しくお願いいたします。

    • ベストアンサー
    • AJAX
  • ExcelからAccessデータを検索するマクロ

    Excel、Accessとも初心者です。 下記を参考にさせて頂いております。 http://okwave.jp/qa/q441987.html これを、(1)~(3)に対応させたいのですが どのように書き換えればよろしいのでしょうか? (1)A1→ A列の最後まで (2)対応するレコードフィールド2   → 規定した複数のレコードフィールド     (例えば、フィールド3とフィールド5とフィールド8) (3)Excel, Accessともに2007です。 (4)検索の経過は表示させない  (少しでも早く処理したい。ひとつひとつ検索結果を表示すると遅くなると聞ききました) ・・・・・・・・・・・・・・・・・・・・・・・・・ Sub Macro1() Dim db As DAO.Database Dim rs As DAO.Recordset Set db = OpenDatabase("c:\abc.mdb") Set rs = db.OpenRecordset("tbl_a", dbOpenDynaset) rs.FindFirst "[フィールド1]='" & Range("A1").Value & "'" If rs.NoMatch Then   Range("B1").Value = "" Else   Range("B1").Value = rs![フィールド2] End If rs.Close Set rs = Nothing Set db = Nothing End Sub ・・・・・・・・・・・・・・・・・・・・・・・・・ よろしくご教授お願いします。

専門家に質問してみよう