Nokogiri и XPath помогают - PullRequest
       9

Nokogiri и XPath помогают

8 голосов
/ 25 августа 2010

По общему признанию, я новичок из Нокогири, и я, должно быть, что-то упустил ...

Я просто пытаюсь распечатать узел автора> name из этого XML:

<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns:gd="http://schemas.google.com/g/2005" xmlns:docs="http://schemas.google.com/docs/2007" xmlns="http://www.w3.org/2005/Atom" gd:etag="">
  <category term="http://schemas.google.com/docs/2007#document" scheme="http://schemas.google.com/g/2005#kind"/>
  <author>
    <name>Matt</name>
    <email>Darby</email>
  </author>
  <title>Title</title>
</entry>

Я пытаюсь использовать это, но он ничего не печатает. Казалось бы, ни один узел (даже '*') ничего не возвращает.

  Nokogiri::XML(@xml_string).xpath("//author/name").each do |node|
    puts node
  end

Ответы [ 2 ]

13 голосов
/ 26 августа 2010

Алехандро уже ответил на это в своем комментарии (+1), но я тоже добавляю этот ответ, потому что он не указал код Nokogiri.

Выбор элементов в некотором пространстве имен с помощью Nokogiri с XPath

Элементы, которые вы пытаетесь выбрать, находятся в пространстве имен по умолчанию, которое в данном случае выглядит как http://www.w3.org/2005/Atom. Обратите внимание на атрибут xmlns=" в элементе entry. Вместо этого ваше выражение XPath соответствует элементам, которые не находятся ни в одном пространстве имен. По этой причине ваш код работал без пространств имен

Вам необходимо определить контекст пространства имен для вашего выражения XPath и указать шаги XPath для соответствия элементам в этом пространстве имен. AFAIK должно быть несколько разных способов сделать это с помощью Nokogiri, один из них показан ниже

xml.xpath("//a:author/a:name", {"a" => "http://www.w3.org/2005/Atom"})

Обратите внимание, что здесь мы определяем отображение пространства имен на префикс и используем этот префикс (a) в выражении XPath.

7 голосов
/ 25 августа 2010

По какой-то причине использование remove_namespaces! заставляет вышеуказанный бит работать должным образом.

xml = Nokogiri::XML(@xml_string)
xml.remove_namespaces!
xml.xpath("//author/name").each do |node|
  puts node.text
end

=> "Matt"
...