我正在研究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。
答案 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元素的更多信息。