• 締切済み

フレーム内の要素へのXPATHはどのように書けばよいのでしょうか?

フレーム内の要素へのXPATHはどのように書けばよいのでしょうか? また、それは可能なのでしょうか? 実際には、firefoxのgreasemonkey で、フレームを使ったページ内のテーブル内のデータを取得したいと考えています。 下記のようにやればできるかと思ったのですが、できないようです・・・ var xpath ='/html/frameset/frame[2]/html/body/table/tbody'; var tbody = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.contentDocument; alert(tbody.rows[0].cells[0].firstChild.data); 対象としているサイトの構造は、下記のようになっています。 2つのフレームを含むソース <HTML> <HEAD> <meta http-equiv="Content-Type" content="text/html; charset=x-sjis"> <TITLE>ほげほげ</TITLE> <FRAMESET ROWS="88,*"> <FRAME SRC="frame1.html" NAME="FRM1"> <FRAME SRC="frame2.html" NAME="FRM2"> </FRAMESET> </HTML> frame2.html <HTML> <HEAD> <meta http-equiv="Content-Type" content="text/html; charset=x-sjis"> <TITLE>フレーム2</TITLE> </HEAD> <BODY> <TABLE border="0"> <TR><TD>データ1</TD>・・・</TR> ・・・・・ </TABLE> </BODY> </HTML> 以上です。 はたしてできるのかどうかもわからない状態です。 どうぞ宜しくお願い致します!!!

みんなの回答

回答No.3

>#1 お礼 サンプルでは,それも考えてframeset要素のonload属性で発動するようにしてあるの。

gwky
質問者

お礼

ご回答ありがとうございます。 greasemonkeyの場合、Q4549731-1.xhtml がロードされた後にスクリプトの実行が開始するため、 frameset に onload で関数を実行する処理を追加することができないように思われます。 tbody が nil だったら、所定時間待機するような処理を加えようかと考えています。 もしも、親ページのhtmlを変更することなく、子フレームのロードが 完了したかどうかを確認する方法がありましたらご教示ください。

  • SAYKA
  • ベストアンサー率34% (944/2776)
回答No.2

前にiframeへアクセスするには っていう質問に答えた事があったけど それが参考になるかな? http://okwave.jp/qa2826529.html まずは通常のjavascriptとしてframe越えでデータをもってきてから希望の処理にかける方が無難だと思うよ

回答No.1

=============Q4549731-1.xhtml===================== <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Q4549731 TestCase 1</title> <script type="text/javascript"> //<![CDATA[ function init(){ //greasemonkey使ったことないし,当面使う気もないからそっちでは検証してない //質問文のように続けて一つにまとめるのは無理。 //手元で実験したのは全てXHTMLですが,HTMLでも,XPath中の名前空間接頭辞を取り除き //evaluateメソッドに名前空間リゾルバを指定しなければ動くと思います。 //あと、gooはURIっぽい文字列(http://の後に連続するSP以外のprintableなASCII文字からなる //文字列の中で最長のものの後ろにNO WIDTH SPACEをつけるので取り除いて各XHTML文書をwell-formedにしてから //やってみてください。 var doc= document.getElementById("hoge").contentDocument; var xpath ="/xhtml:html/xhtml:body/xhtml:table/xhtml:tbody"; //コンテキストノードが属するドキュメントでないと,document.evaluateが通用しません。 //document関数で出来るかな、とも思ったけど、document関数はXPath 1.0にはない。あるのはXSLT 1.0 //個人的な好みで,FIRST_ORDERED_NODEではなくなってます。 var tbody = doc.evaluate(xpath, doc, resolveNamespace, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); //DOM Level 2 HTMLで、HTMLTableSectionやHTMLTableElementにはcellsはない //ちなみにHTMLの時にFirefoxが,書かれていないように見えるtbody要素を補うのは妥当。HTML 4.01とXHTML 1.0の //table要素型,tbody要素型の定義は異なる。前者はtbodyが1つ以上必須だが,tbodyの開始タグ・終了タグが省略可能 //後者はなくてもよい alert(tbody.snapshotItem(0).getElementsByTagName("tr")[0].getElementsByTagName("td")[0].textContent); } function resolveNamespace(s){ //本来はHashTable等でまともに実装すべき if (s == "xhtml"){ return "http://www.w3.org/1999/xhtml"; }else{ throw new Error("invalid prefix"); } } //]]> </script> </head> <frameset cols="50%,50%" onload="init();"> <frame id="hoge" src="Q4549731-2.xhtml" /> <frame src="Q4549731-3.xhtml" /> </frameset> </html> =====================Q4549731-2.xhtml============== <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Q4549731 TestCase 1</title> </head> <body> <table> <tbody> <tr><td>あ</td></tr> </tbody> </table> </body> </html> =====================Q4549731-3.xhtml============== <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Q4549731 TestCase 1</title> </head> <body> <p>い</p> </body> </html>

gwky
質問者

お礼

ご回答いただきましてありがとうございます!! 私が取得したいサイトでは、フレームにIDがついていないので、 var doc= document.getElementById("hoge").contentDocument; はできませんでした。 そこで、ヒントにさせていただいて、ここもxpathを使ってやろうとして、 下記のようにやったら、うまくいきました。 しかし、alert をコメントにすると、うまくいく場合と、いかない場合と、が出てしまいます。フレームの読み込みが完了していないときに 実行される場合があるということなのでしょうか・・・。 alertをなくしてもうまくいく方法をご存知でしたら教えていただけませんでしょうか? var xpath ='/html/frameset/frame[2]'; // なぜかわからないけど、alertが必要 alert("hoge"); var aframe = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.contentDocument; var xpath ='/html/body/table/tbody'; var tbody = aframe.evaluate(xpath, aframe, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0); alert(tbody.rows[1].cells[1].firstChild);