Javascript XPath查找文本为+;他们的子孙,;符合特定标准的兄弟姐妹

Javascript XPath查找文本为+;他们的子孙,;符合特定标准的兄弟姐妹,javascript,html,xpath,greasemonkey,Javascript,Html,Xpath,Greasemonkey,背景: 我正在努力改进我发现的一个问题。 该脚本以外币标记价格,并可以将其转换为您选择的货币 主要问题: 当价格与标签一起列出时,如何使脚本处理,例如: <b><i>9.</i></b><sup>95</sup>EUR 由于脚本需要快速,我试图避免过多地跨过DOM… 是否有XPath专家可以为此提供一些智能解决方案? 问题的更详细描述: 我现在拥有查找文本节点的代码: var re_skip = /^(SCRIPT|IF

背景:
我正在努力改进我发现的一个问题。
该脚本以外币标记价格,并可以将其转换为您选择的货币

主要问题:
当价格与标签一起列出时,如何使脚本处理,例如:

<b><i>9.</i></b><sup>95</sup>EUR
由于脚本需要快速,我试图避免过多地跨过DOM…
是否有XPath专家可以为此提供一些智能解决方案?


问题的更详细描述:
我现在拥有查找文本节点的代码:

var re_skip = /^(SCRIPT|IFRAME|TEXTAREA|STYLE|OPTION|TITLE|HEAD|NOSCRIPT)$/;  // List of elements whose text node-children can be skipped
text = document.evaluate("//text()", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i = text.snapshotLength;
while (i--) {
    el = text.snapshotItem(i);
    if (!el.parentNode || re_skip.test(el.parentNode.nodeName.toUpperCase()) || el.parentNode.className == 'autocurrency') {
        continue;
    }
//  ...
//  (RegEx logic to check if prices can be found in the text)
}

  • 放弃父元素列在“re_skip”中的文本节点的检查也可以在XPath表达式()中完成,对吗?这会增加速度吗

  • 如果改为使用有序XPath类型,我想我不必再包含检查以查看正在解析的文本节点的父节点是否为(即,脚本围绕匹配的价格添加的值)

  • 如果我理解正确,那么在这种情况下不能使用normalize-space()(如建议的那样),因为脚本在匹配的数量周围添加了一个,并且我们需要保留正确的索引,用于输入该数量的位置

  • XPath是否有办法只允许在货币值之间使用某些(内联)元素?或者它可以这样做:“当找到包含文本的节点时,还可以将其所有子节点(及其子节点等)包含在匹配中-除非子节点是块类型元素。”(或者它应该读为:“……除非子节点是DIV、P、TABLE或re_skip中的任何元素”)

我可以重新编写正则表达式来处理诸如“$174.99”之类的文本,只要找到这些文本字符串——最好使用XPath,因为我知道这比单步遍历DOM要快得多

非常感谢您在这方面给我的任何帮助

---------------------------------------------------------------
编辑:
好的,我现在意识到这个问题需要一些澄清和例子,所以他们来了。网页的外观可能如下所示:

<body>
  <div>
    <span>9.95 <span>EUR</span></span><br />
    <span>8.<sup>95</sup></span>AU$<br />
    <table>
      <thead>
        <tr>
          <th>Bla</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><b>7</b>.95kr</td>
        </tr>
      </tbody>
    </table>
    <div>Bla bla</div>
    6.95 <span>GBP</span>
  </div>
  <div><img src="" /><img src=""><span>Bla bla bla</span></div>
</body>

9.95欧元
8.95澳元
布拉 7.95kr 布拉布拉 6.95英镑 呜呜呜呜
现在,在这个例子中,开销并没有那么大——我可以将整个源代码作为字符串直接输入到查找价格的正则表达式中。但通常情况下,页面会有很多非文本元素,如果我没有使用快速XPath解析文本,那么脚本的速度会非常慢。因此,我正在寻找一个XPath表达式,它可以在上面的示例中找到不同的文本,而不仅仅是文本内容,因为我们还需要围绕价格部分的标记(稍后将围绕匹配的价格创建一个新的标记,包括围绕价格部分的任何内联元素)

我不知道XPath可以返回什么,但是我需要从上面的示例页面中获取以下字符串:

"9.95 <span>EUR</span>"       (or possibly: "<span>9.95 <span>EUR</span></span>")
"<span>8.<sup>95</sup></span>AU$"
"Bla"                         (or possibly: "<th>Bla</th>")
"<b>7</b>.95kr"               (or possibly: "<td><b>7</b>.95kr</td>")
"Bla bla"                     (or possibly: "<div>Bla bla</div>")
"6.95 <span>GBP</span>"
"Bla bla bla"                 (or possibly: "<span>Bla bla bla</span>")
“9.95欧元”(或可能是“9.95欧元”)
“8.95澳元”
“Bla”(或者可能是“Bla”)
“7.95kr”(或者可能是“7.95kr”)
“布拉布拉”(或者可能是“布拉布拉”)
“6.95英镑”
“布拉布拉布拉布拉”(或者可能是“布拉布拉布拉布拉”)

然后,这些字符串可以由查找价格的正则表达式解析

当然,您可以使用类似于
/*[not(self::script | self::textarea | self::style)]///text()的路径来查找元素节点的那些文本节点后代,这些文本节点不是“script”、“textarea”、“style”中的一个。因此,您没有必要进行正则表达式测试,您可以使用XPath表达该需求。我说不出这是否更好,您必须检查要使用Greasemonkey脚本的浏览器的XPath实现。

感谢Martin确认我提到的使用“not”符号排除某些元素的想法。希望您或其他人对我提出的主要问题也有一些想法——不仅包括每个文本节点的文本,还包括其子节点(包括它们的标记,而不仅仅是它们的文本内容)。再次感谢!如果您提供一个具有代表性的、完整的(但不是不必要的大)XML文档,并清楚地指出要选择的tect节点,那么这个问题将更有意义。如果不这样做,这就是一个好问题的坏例子。对不起,你在说什么?我想我已经清楚地将这个问题标记为与Greasemonkey、JavaScript、HTML和XPath相关的问题。我认为很明显,这个Greasemonkey JavaScript是在网页(HTML)上运行的。我甚至提到了可能会遇到哪种HTML元素(尽管脚本不应该硬编码哪些元素是允许的,只是哪些不允许)OK,在阅读了几遍文本之后,我意识到它确实需要一些调整和澄清。我将编辑这个问题。也许知道XPath只在XML(Infoset)上运行而不在HTML上运行会有所帮助——这两者的交叉点是XHTML。至于Javascript和所有类型的猴子,不要指望XPath专家对它们了解太多。如果希望XPath表达式选择特定节点,则必须:1。提供XML文档;2.明确定义应选择的节点。如果不提供这些信息,就等同于征求关于明天天气的建议。我只是用一些说明和例子编辑了这个问题。在这样做之后
"9.95 <span>EUR</span>"       (or possibly: "<span>9.95 <span>EUR</span></span>")
"<span>8.<sup>95</sup></span>AU$"
"Bla"                         (or possibly: "<th>Bla</th>")
"<b>7</b>.95kr"               (or possibly: "<td><b>7</b>.95kr</td>")
"Bla bla"                     (or possibly: "<div>Bla bla</div>")
"6.95 <span>GBP</span>"
"Bla bla bla"                 (or possibly: "<span>Bla bla bla</span>")