Greasemonkey,XPath:查找表行中的所有链接

时间:2009-07-03 09:10:39

标签: xpath greasemonkey

假设:

<tr>
  <td><a href="http://foo.com">Keyword 1</a></td>
  <td><a href="http://bar.com">Keyword 2</a></td>
  <td><a href="http://wombat.com">Keyword 3</a></td>
</tr>

<tr>
  <td><a href="http://blah.com">Keyword 4</a></td>
  <td><a href="http://woof.com">Keyword 5</a></td>
  <td><a href="http://miaow.com">Keyword 6</a></td>
</tr>

我需要匹配表格单元格中的每个URI。关键字在整个文档中是一致的。我可以毫不费力地匹配整个文档的链接:

var links_in_document = document.evaluate(
  "//a[starts-with(text(),'Keyword')]",
  document,
  null,
  XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
  null);

然而,即使我有一个简单的方法来引用TR节点,我似乎无法找到正确的XPath来获取行中的链接。下面的片段似乎给了我第一个TD的第一个链接,但不是其余的。帮助

var links_in_row = document.evaluate(
  ".//a[starts-with(text(),'Keyword')]",
  row,
  null,
  XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
  null);

(其中'row'是上下文节点)。

编辑:也许我不清楚,我可以从文档级别找到链接就好了。我试图通过使用TR节点作为XPath的上下文来隔离单行中的链接。

编辑:解决方案,感兴趣。我正在处理的破坏的标记没有id属性,所以我添加了一些并且能够继续。片段:

var exhibit_link;
for( var i = 0; i < all_exhibit_links.snapshotLength; i++ ) {
  exhibit_link = all_exhibit_links.snapshotItem( i );

  // The rows have no unique ID, so we need to give them one.
  // This will give the XPath something to 'latch onto'.
  exhibit_link.parentNode.parentNode.id = 'ex_link_row_' + i.toString();

  exhibit_link.addEventListener( "click", 
    function( event ) {
      var row_id = event.target.parentNode.parentNode.id;

      // Find only those links that are within rows with the corresponding id
      var row_links = document.evaluate(
        "id('" + row_id + "')/td/a[starts-with(text(),'Exhibit')]",
        document,
        null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null);

      // Open each link in a new tab
      for( var j = 0; j < row_links.snapshotLength; j++ ) {
        row_link = row_links.snapshotItem( j );
        GM_openInTab( row_link.href );
      }

      // Suppress the original function of the link
      event.stopPropagation();
      event.preventDefault();
    }, 
    true );
}

3 个答案:

答案 0 :(得分:3)

使用您的html示例和以下代码在JavaScript Shell中进行快速测试:

var links_in_row = document.evaluate( ".//a[starts-with(text(),'Keyword')]"
          , document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i = 0;
while( (link = links_in_row.snapshotItem(i) ) != null) {
   print(link.innerHTML);i++;
}

打印出来:

Keyword 1
Keyword 2
Keyword 3

表明它工作正常。 只有我做的改变不是从行级开始,而是在文档......

答案 1 :(得分:1)

根据bert写的内容,这对我有用。

var rows = document.evaluate( "//tr"
          , document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i = 0;
while( (row = rows.snapshotItem(i) ) != null) {
    print( 'NEW ROW----');
    var links = document.evaluate(".//a[starts-with(text(),'Keyword')]",
                                  row, null, 
                                  XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
    var k = 0;
    while ((link = links.snapshotItem(k)) != null) {
       print( link.innerHTML );
       k++;
    }
    i++;
}

打印出来:

NEW ROW----
Keyword 1
Keyword 2
Keyword 3
NEW ROW----
Keyword 4
Keyword 5
Keyword 6

我认为在复制粘贴的内容之外缺少一些东西。

bert应该得到这个恕我直言的答案。

答案 2 :(得分:0)

尝试:

descendant::*[self::a[starts-with(text(), 'Keyword')]]