【问题标题】:xpath with contains throws error if string starts with a number如果字符串以数字开头,则包含包含的 xpath 会引发错误
【发布时间】:2013-12-05 15:52:43
【问题描述】:

我在使用 nokogiri 和 xpath 时遇到了一个奇怪的问题。我想解析一个 HTML 文档并通过 href 值和它们包含的锚文本获取所有链接。

到目前为止,这是我的 xpath:

    xpath = "//a[contains(text(), #{link['anchor_text']}) and @href='#{link['target_url']}']"
    a = doc.search(xpath)

只要 link['anchor_text'] 是一个没有数字的字符串,它就可以正常工作。

如果我试图获取带有锚文本“11example”的链接,则会引发以下错误:

    Invalid expression: //a[contains(text(), 11example) and @href='http://www.example.com/']

也许这只是一个愚蠢的错误,但我不明白为什么会发生此错误。如果我在 xpath 中的 #{link['anchor_text']} 周围加上引号,则没有任何效果。

编辑:这是示例 HTML:

<!DOCTYPE html>
<head>
  <title>Example.com</title>
</head>
<body>
<p>
<strong>Here is some text</strong><br />
<a href="example.com" target="_blank">11example</a>Some text here and there
</p>
<p>
<strong>Another text</strong><br />
<a href="example.com/test" target="_blank">example.com</a>Some text here and there
</p>
</body>

Edit2:如果我在 irb 控制台中手动运行这些查询,一切都会按预期工作,但前提是我将文本放在引号中。

提前致谢!

亲切的问候, 疯子

【问题讨论】:

  • 把示例 HTML 也给我们..
  • 抱歉,我添加了 HTML。

标签: ruby-on-rails ruby xpath nokogiri


【解决方案1】:

简单的答案是您缺少#{link['anchor_text']} 周围的引号,就像您在#{link['target_url']} 周围一样。完整的 XPath 应该是

xpath = "//a[contains(text(), '#{link['anchor_text']}') and @href='#{link['target_url']}']"

当您不以数字开头时,它似乎工作(至少不会产生错误)的原因是字符串被解释为节点查询。例如,Nokogiri 在&lt;a&gt; 标签内寻找一个名为&lt;example.com&gt; 的标签,然后将其转换为字符串,并查看&lt;a&gt; 标签的文本节点是否包含该字符串。如果标签不存在(如本例中),则contains 的结果始终为真。

作为演示,用 HTML:

<a href="example.com"><q>foo</q>example</a>
<a href="example.com"><q>foo</q>foo</a>
<a href="example.com">foo</a>

然后查询

doc.search("//a[contains(text(), q)]")

不匹配第一个&lt;a&gt;标签,但匹配第二个和第三个。

当字符串以数字开头时,它不能被解析为节点查询,因为以数字开头的名称不是有效的 XML(或 HTML)元素名称,因此会出现错误。

【讨论】:

  • '#{link['anchor_text']}' 真的有用吗? XPath 如何知道anchor 之前的' 并不表示字符串#{link[ 的结尾?
  • @LarsH #{...} 的内容首先由 Ruby 进行插值,然后再传递给 Nokogiri。因此,如果 link['anchor_text'] 的计算结果为 11example(在 Ruby 中),那么 Nokogiri 看到的字符串将是 '11example'(带有外引号)。 Ruby 处理嵌套在 #{...} 中的引号就像这样。
  • 啊,愚蠢的我。感谢您的详细回答和解释!
猜你喜欢
  • 1970-01-01
  • 2017-08-08
  • 2012-07-14
  • 2020-02-14
  • 2014-05-21
  • 2019-03-15
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多