【问题标题】:XPath syntax for searching generic text?用于搜索通用文本的 XPath 语法?
【发布时间】:2014-06-09 10:00:45
【问题描述】:

我有一个使用 Nokogiri 解析的 HTML 页面,我应该找到包含在每个元素中的通用文本。它是哪个元素并不重要,它应该与我传递给contains() 的文本匹配。

我目前能够得到的结果非常通用,我不确定我是否正确解释了 XPath 文档:

html = Nokogiri::HTML(page['result'])
puts html.xpath("/*[contains(., 'Foobar')]")

我想要的是包含“Foobar”的元素,但库正在返回整个页面。我做错了什么?

【问题讨论】:

  • 试试//*[contains(child::text(), 'Foobar')]

标签: ruby parsing xpath nokogiri


【解决方案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"]

【讨论】:

    【解决方案2】:

    您尝试的 XPath 返回包含 Foobar 文本的所有元素包括那些提到的元素的祖先(因为祖先也被认为包含 Foobar 文本,尽管 间接 )。

    您可以通过这种方式仅获取直接包含Foobar文本的元素:

    puts html.xpath("/*[contains(text(), 'Foobar')]")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 2010-09-27
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多