Nokogiri и XPath помощь

Правда, я новичок Nokogiri, и я должен быть что-то не хватает ...

Я просто пытаюсь напечатать узел автор> имя из этого 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

person Matt Darby    schedule 25.08.2010    source источник


Ответы (2)


Алехандро уже ответил на этот вопрос в своем замечании (+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.

person jasso    schedule 26.08.2010

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

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

=> "Matt"
person Matt Darby    schedule 25.08.2010
comment
Причина заключается в том, что все элементы находятся под http://schemas.google.com/docs/2007 имен URI. Вы должны объявить связывание bettween этого URI в какой-то префикс, скажем atom, а затем XPath expresion должен быть /*/atom:author/atom:name - person ; 25.08.2010