Использование Nokogiri и XPath для получения узлов с несколькими атрибутами - PullRequest
6 голосов
/ 29 августа 2010

Я пытаюсь использовать Nokogiri для разбора файла HTML с какой-то довольно эксцентричной разметкой.В частности, я пытаюсь получить 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.Я могу получить div с одним атрибутом id без проблем, но я не могу найти способ заставить Nokogiri захватывать div с обоими классами ids и .Так что они отлично работают:

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

content = @doc.css('div#foo')

Но они ничего не возвращают:

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

content = @doc.xpath("div#bar")

Есть ли что-то очевидное, что я здесь упускаю?

Ответы [ 4 ]

4 голосов
/ 29 августа 2010

Я могу получить div с одним идентификатором Атрибут без проблем, но я не могу выяснить способ получения Nokogiri чтобы захватить div с обоими идентификаторами и классы.

Вы хотите :

//div[id='bar' and class='baz bang' and style='display: block;']
2 голосов
/ 29 августа 2010

У меня работает следующее.

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 голос
/ 30 августа 2010

Вы писали:

Я пытаюсь схватить div, которые имеют оба идентификатора, несколько классов и стилей определен

А

Я пытаюсь схватить <dl>, который находится внутри проблемы div

Итак, этот XPath 1.0:

//div[@id][contains(normalize-space(@class),' ')][@style]/dl
1 голос
/ 29 августа 2010

Я думаю content = @doc.xpath("div#bar") - это опечатка, которая должна быть content = @doc.css("div#bar") или лучше content = @doc.css("#bar").Первое выражение в вашем втором фрагменте кода выглядит нормально.

...