我有一个使用Nokogiri解析的HTML页面,我应该找到包含在每个元素中的通用文本。它与哪个元素无关,它应该与我传递给contains()
的文本匹配。
我现在能够获得的结果非常通用,我不确定我是否正确解释了XPath文档:
html = Nokogiri::HTML(page['result'])
puts html.xpath("/*[contains(., 'Foobar')]")
我想要的是包含“Foobar”的元素,但是库正在返回整个页面。我做错了什么?
答案 0 :(得分:1)
将/
与XPath一起使用意味着从文档的根目录开始,这不是您想要的。 xpath
将找到所有匹配的元素,这意味着还将找到包含所需文本的所有祖先节点,从而导致根目录下的所有内容满足条件。
以下是一个显示此示例的示例:
require 'nokogiri'
xml = '<html><body><div><p>foobar</p></div></body></html>'
doc = Nokogiri::XML(xml)
doc.xpath("/*[contains(., 'foobar')]").map(&:to_html)
# => ["<html><body><div><p>foobar</p></div></body></html>"]
我会这样搜索:
require 'nokogiri'
xml = '<html><body><div><p id="1">foobar</p></div><div><p id="2">foobar</p></div></body></html>'
doc = Nokogiri::XML(xml)
doc.search("//text()[contains(., 'foobar')]").map{ |t| t.parent.to_html }
# => ["<p id=\"1\">foobar</p>", "<p id=\"2\">foobar</p>"]
这将在所有文本节点中搜索所需的文本,然后检索该节点的父节点,这似乎更有用。
这是相同的代码,用于检索XPath到节点:
doc.search("//text()[contains(., 'foobar')]").map{ |t| t.parent.path }
# => ["/html/body/div[1]/p", "/html/body/div[2]/p"]
答案 1 :(得分:0)
您尝试过的XPath会返回包含Foobar
文本的所有元素,包括这些元素的祖先(因为祖先也被视为包含Foobar
文本,尽管间接 )。
您可以这样做,只获取直接包含Foobar
文字的元素:
puts html.xpath("/*[contains(text(), 'Foobar')]")