2016-04-05 11 views
2

getElementXPath function from FirebugをCasperJSで動作させようとしていますが、動作させるために適切な場所を見つけることができないようです。ここで私がこれまでに持っていたのは、 "id"タグをすでに持っているオブジェクトに対してのみ機能しますが、IDの代わりにXPathを使用しているためほとんど役に立ちません(ほとんどのオブジェクトにはIDがありません)CasperJSで指定された要素のXPathを計算する

要素が既に「ID」タグを有する場合2のみ正しいパスを出力

セット:

casper.then(function() { 
    var Element = this.evaluate(function(){ 
     var elm = document.querySelector('[class="h4"]'); 
     return getElementXPath(elm); //Set 1 
     //return elm; //Set 2 
    }); 

    console.log('xpath: '+ Element); //Set 1 
    //console.log('xpath: '+ getElementXPath(Element)); //Set 2 
}); 

セット1は常に「ヌルのXPath」を出力します。 "XPathの:// * [ID =" ボタン "]"

セット2は、そうでない場合は、出力の最後のタグすなわちだろう "のxpath:/ A" または "のxpath:/スパン"

はここからgetElementXPath機能ですJSファイルの先頭に貼り付けたFirebug。

function getElementXPath(element) 
{ 
    if (element && element.id) 
     return '//*[@id="' + element.id + '"]'; 
    else 
     return getElementTreeXPath(element); 
}; 

function getElementTreeXPath(element) 
{ 
    var paths = []; 
    // Use nodeName (instead of localName) so namespace prefix is included (if any). 
    for (; element && element.nodeType == Node.ELEMENT_NODE; element = element.parentNode) 
    { 
     var index = 0; 
     var hasFollowingSiblings = false; 
     for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) 
     { 
      // Ignore document type declaration. 
      if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE) 
       continue; 
      if (sibling.nodeName == element.nodeName) 
       ++index; 
     } 

     for (var sibling = element.nextSibling; sibling && !hasFollowingSiblings; 
      sibling = sibling.nextSibling) 
     { 
      if (sibling.nodeName == element.nodeName) 
       hasFollowingSiblings = true; 
     } 
     var tagName = (element.prefix ? element.prefix + ":" : "") + element.localName; 
     var pathIndex = (index || hasFollowingSiblings ? "[" + (index + 1) + "]" : ""); 
     paths.splice(0, 0, tagName + pathIndex); 
    } 
    return paths.length ? "/" + paths.join("/") : null; 
}; 
+0

https://github.com/firebug/firebug/blob/master/extension/content/firebug/lib/xpath.js – projectgonewrong

答えて

1

あなたは"page.error"イベントに耳を傾け、あなたはこれを使用すると、ページ内にそのコードを含める方法とは何かを持っている

Error: ReferenceError: Can't find variable: getElementXPath

のようなものを参照してください。以下の完全なスクリプトは、私の作品:

var casper = require('casper').create(); 

// http://docs.casperjs.org/en/latest/events-filters.html#page-error 
casper.on("page.error", function(msg, trace) { 
    this.echo("Error: " + msg); 
    // maybe make it a little fancier with the code from the PhantomJS equivalent 
}); 

casper.start('http://example.com'); 

casper.then(function() {    
    this.evaluate(function(){ 
     window.getElementXPath = function(element) 
     { 
      if (element && element.id) 
       return '//*[@id="' + element.id + '"]'; 
      else 
       return getElementTreeXPath(element); 
     }; 

     function getElementTreeXPath(element) 
     { 
      var paths = []; 
      // Use nodeName (instead of localName) so namespace prefix is included (if any). 
      for (; element && element.nodeType == Node.ELEMENT_NODE; element = element.parentNode) 
      { 
       var index = 0; 
       var hasFollowingSiblings = false; 
       for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) 
       { 
        // Ignore document type declaration. 
        if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE) 
         continue; 
        if (sibling.nodeName == element.nodeName) 
         ++index; 
       } 

       for (var sibling = element.nextSibling; sibling && !hasFollowingSiblings; 
        sibling = sibling.nextSibling) 
       { 
        if (sibling.nodeName == element.nodeName) 
         hasFollowingSiblings = true; 
       } 
       var tagName = (element.prefix ? element.prefix + ":" : "") + element.localName; 
       var pathIndex = (index || hasFollowingSiblings ? "[" + (index + 1) + "]" : ""); 
       paths.splice(0, 0, tagName + pathIndex); 
      } 
      return paths.length ? "/" + paths.join("/") : null; 
     }; 
    }); 

    this.echo(this.evaluate(function(){ 
     return getElementXPath(document.querySelector("a")); 
    })); 
}); 

casper.run(); 

出力:

 
/html/body/div/p[2]/a 

トリックは、ページのコンテキスト内でグローバルスコープでgetElementXPathが利用できるようにすることです。これは、変数をwindow.getElementXPathに設定することで簡単に実行できます。

+0

なぜjquery $( "a:contains( 'text') ')がインプレースで動作しないのですか?入力パラメータのdocument.querySelector( "a")の? – projectgonewrong

+0

'$(" a:contains( 'text') ")'の出力はjQueryコレクションであり、要素ではありません。コレクションに少なくとも1つの要素が含まれていることを確認する必要があります。 'var al = $(" a:contains( 'text') "); if(al.length> 0){...} 'し、要素' al [0] 'を取得します。 –

関連する問題