如何使用Nokogiri和XPath获取具有多个属性的节点

问题描述 投票:7回答:5

我正在尝试使用Nokogiri来解析带有一些相当古怪的标记的HTML文件。具体来说,我正在尝试获取同时定义了ID,多个类和样式的div。

标记看起来像这样:

<div id="foo">
  <div id="bar" class="baz bang" style="display: block;">
    <h2>title</h2>
    <dl>
      List of stuff
    </dl>
  </div>
</div>

我正在尝试抓住问题<dl>中的<div>。我可以毫无问题地获得具有单个id属性的div,但我想不出一种方法来让Nokogiri来获取两个ids [[和类的div。

所以这些工作正常:

content = @doc.xpath("//div[id='foo']") content = @doc.css('div#foo')

但是这些都不返回任何内容:

content = @doc.xpath("//div[id='bar']") content = @doc.xpath("div#bar")

我在这里明显缺少什么吗?
ruby xpath nokogiri
5个回答
4
投票
我可以使用一个ID获得div属性没有问题,但我不能找出获取Nokogiri的方法用ID和ID抓取div类。

您想要:

//div[id='bar' and class='baz bang' and style='display: block;']

3
投票
以下为我工作。

require 'rubygems' require 'nokogiri' html = %{ <div id="foo"> <div id="bar" class="baz bang" style="display: block;"> <h2>title</h2> <dl> List of stuff </dl> </div> </div> } doc = Nokogiri::HTML.parse(html) content = doc .xpath("//div[@id='foo']/div[@id='bar' and @class='baz bang']/dl") .inner_html puts content


1
投票
我认为content = @doc.xpath("div#bar")是一个错字,应该为content = @doc.css("div#bar")或更佳的content = @doc.css("#bar")。您的第二个代码块中的第一个表达式似乎没问题。

1
投票
您写道:

我正在尝试获取具有以下内容的divid,多个类和样式已定义

我正在尝试抓住位于问题div内的<dl>

所以,这个XPath 1.0:

//div[@id][contains(normalize-space(@class),' ')][@style]/dl


0
投票
我强烈建议使用CSS选择器而不是XPath作为起点,因为CSS更具可读性,并且不太可能导致视觉噪音。

require 'nokogiri' doc = Nokogiri::HTML(<<EOT) <div id="foo"> <div id="bar" class="baz bang" style="display: block;"> <h2>title</h2> <dl> List of stuff </dl> </div> </div> EOT

解析后,使用CSS查找<div ... id="foo">

doc.at('div#foo').to_html # => "<div id=\"foo\">\n" + # " <div id=\"bar\" class=\"baz bang\" style=\"display: block;\">\n" + # " <h2>title</h2>\n" + # " <dl>\n" + # " List of stuff\n" + # " </dl>\n" + # " </div>\n" + # "</div>"

<div id="bar">

doc.at('div#bar').to_html # => "<div id=\"bar\" class=\"baz bang\" style=\"display: block;\">\n" + # " <h2>title</h2>\n" + # " <dl>\n" + # " List of stuff\n" + # " </dl>\n" + # " </div>"

我们可以用两个类名搜索标签:

doc.at('.baz.bang').to_html # => "<div id=\"bar\" class=\"baz bang\" style=\"display: block;\">\n" + # " <h2>title</h2>\n" + # " <dl>\n" + # " List of stuff\n" + # " </dl>\n" + # " </div>"

而且我们可以查找带有两个类及其嵌入式<dl>标签的显式div:

doc.at('div.baz.bang dl').to_html # => "<dl>\n" + # " List of stuff\n" + # " </dl>"

或什至按ID和类别:

doc.at('div#bar.baz.bang').to_html # => "<div id=\"bar\" class=\"baz bang\" style=\"display: block;\">\n" + # " <h2>title</h2>\n" + # " <dl>\n" + # " List of stuff\n" + # " </dl>\n" + # " </div>"

以及[<dl>

doc.at('div#bar.baz.bang dl').to_html # => "<dl>\n" + # " List of stuff\n" + # " </dl>"

我正在使用at,这等同于使用search(...some selector...).first。 Nokogiri支持search以及cssxpath,这是CSS和XPath的变体,它们返回NodeSet,并支持atat_cssat_xpath返回Node。了解“ NodeSet”和“ NodeSet”之间的区别以及它们与Nodetext的关系非常重要,因此请阅读文档。
© www.soinside.com 2019 - 2024. All rights reserved.