如果字符串以数字开头,则包含throws的xpath错误

mad*_*pie 1 ruby xpath ruby-on-rails nokogiri

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

到目前为止这是我的xpath:

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

只要link ['anchor_text']是没有数字的字符串,这就可以正常工作.

如果我试图获取锚文本"11example"的链接,则会抛出以下错误:

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

也许这只是一个愚蠢的错误,但我不明白为什么会出现这种错误.如果我在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>
Run Code Online (Sandbox Code Playgroud)

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

提前致谢!

亲切的问候,madhippie

mat*_*att 5

简单的答案就是你错过了周围的报价#{link['anchor_text']},就像你身边的一样#{link['target_url']}.完整的XPath应该是

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

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

作为演示,使用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>
Run Code Online (Sandbox Code Playgroud)

然后是查询

doc.search("//a[contains(text(), q)]")
Run Code Online (Sandbox Code Playgroud)

与第一个<a>标记不匹配,但与第二个和第三个标记匹配.

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