获取当前节点和另一个节点之间的所有节点而不使用current()?

时间:2009-03-26 00:31:01

标签: firefox xpath greasemonkey

我正在研究Greasemonkey脚本,该脚本需要在两个其他节点之间的每个节点上运行。目前,我正在使用(越来越复杂的)XPath表达式获得第一个节点。我有另一个表达式来获取“之间”节点,但它包含两次初始表达式并且变得相当长。这是一个早期版本,只包含两个“子句”:

var xpHeader   = "//h2[a/@name='section-References' or a/@name='References']";
var xpContents = "//h2[a/@name='section-References' or a/@name='References']/following-sibling::*[following-sibling::h2[1] = //h2[a/@name='section-References' or a/@name='References']/following-sibling::h2[1]]"

我正在寻找的是一种基于上下文节点选择“内容”而不是多次重新包含原始表达式的方法 - “头”表达式将非常快速地变得相当复杂。我知道这可以使用current()函数在XSLT中完成,但当然在vanilla XPath中不可用:

<xsl:template match="//h2[a/@name='section-References' or a/@name='References']">
    <xsl:for-each select="following-sibling::*[following-sibling::h2[1] = current()/following-sibling::h2[1]]">
        <!-- do stuff -->
    </xsl:for-each>
</xsl:template>

当我输入这个时,我发现在这一点上,使用DOM收集内容而不是XPath可能更容易,但我仍然有兴趣知道这是否可以做到

该脚本的原始版本为available on UserScripts.org

3 个答案:

答案 0 :(得分:2)

虽然您正在编写XPath表达式,但对于Javascript,它们只是字符串。你可以连接字符串。

var xpContents = xpHeader + "/following-sibling::*["
  + "following-sibling::h2[1] = " + xpHeader + "/following-sibling::h2[1]"
  + "]";

现在,您的标题表达式可以根据需要变得复杂,而不会影响内容表达式赋值的复杂性。 XPath求值程序仍然必须解析整个字符串,如果没有查询优化,那么它可能会被多次评估,但即使这样也可能足够快,无关紧要。

答案 1 :(得分:2)

一旦你使用XPath来收集那个级别的东西,听起来使用DOM会更容易一些。假设你没有使用框架,那就是:

var nodes = document.evaluate("//h2[a/@name='section-References' or a/@name='References']/following-sibling::*", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var contents=[];
if (nodes.snapshotLength>0) contents.push(new Array());
var currentGroup=0;
for (var i=0;i<nodes.snapshotLength;i++) {
  if (nodes.shapshotItem(i)==<your favorite way to detect the right flavor of h2 element>) {
    currentGroup++;
    contents.push(new Array());
    continue;
  }
  contents[currentGroup].push(nodes.snapshotItem(i));
}

它有点冗长,但你最终会在有趣的h2节点之间找到一系列项目数组。

答案 2 :(得分:1)

您可以使用jQuery或其他JavaScript框架来更轻松地使用DOM。

示例:

// ==UserScript==
// @name           MyScript
// @namespace      http://example.com
// @description    Example
// @include        *
//
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js
// ==/UserScript==

$('h2[some crazy attributes...]').each(function() {
  // Do something
});

查看jQuery参考,了解有关通过XPath属性选择和遍历DOM元素的更多信息。

jQuery Selectors

jQuery Traversal

jQuery next()

jQuery nextAll()