2013-06-12 2 views
0

Контекст: Я разбираю XML-файл, используя драгоценный камень libxml-ruby. Мне нужно запросить XML-документ для набора узлов, используя метод XPath find. Затем мне нужно обработать каждый узел отдельно, запросив их еще раз, используя метод XPath find.LIBXML-RUBY> Xpath context

Проблема: При попытке запросить возвращенные узлы по отдельности, метод XPath find запрашивает весь документ, а не только в узле:

Пример кода:

require 'xml' 

string = %{<?xml version="1.0" encoding="iso-8859-1"?> 
<bookstore> 
    <book> 
    <title lang="eng">Harry Potter</title> 
    <price>29.99</price> 
    </book> 
    <book> 
    <title lang="eng">Learning XML</title> 
    <price>39.95</price> 
    </book> 
</bookstore>} 

xml = XML::Parser.string(string, :encoding => XML::Encoding::ISO_8859_1).parse 
books = xml.find("//book") 
books.each do |book| 
    price = book.find("//price").first.content 
    puts price 
end 

В этом script возвращает 29.99 дважды. Я думаю, что у этого должно быть что-то с настройкой контекста XPath, но я еще не понял, как это сделать.

+0

Я очень рекомендую использовать Nokogiri для анализа XML. Это стандартный стандарт для Ruby. –

+0

Я действительно начал использовать Nokogiri и столкнулся с такой же точной проблемой. Я перешел на libxml-ruby, надеясь, что все будет по-другому, но та же проблема сохраняется. –

+0

Ну ... когда проблема следует за вами, вы знаете, что это не в библиотеке. :-) Был там, сделал это слишком много раз, чтобы помнить. Придерживайтесь Нокогири; Это круто. –

ответ

2

Первая проблема, которую я вижу, - book.find("//price").

//price означает «начать в верхней части документа и смотреть вниз. Это, безусловно, не то, что вы хотите сделать. Вместо этого я думаю, что вы хотите, чтобы заглянуть внутрь book первый price.

Использование Nokogiri, я «d использование CSS селекторы, потому что они более легко на глаз и, как правило, сделать то же самое:

require 'nokogiri' 

string = %{<?xml version="1.0" encoding="iso-8859-1"?> 
<bookstore> 
    <book> 
    <title lang="eng">Harry Potter</title> 
    <price>29.99</price> 
    </book> 
    <book> 
    <title lang="eng">Learning XML</title> 
    <price>39.95</price> 
    </book> 
</bookstore>} 

xml = Nokogiri::XML(string) 
books = xml.search("book") 
books.each do |book| 
    price = book.at("price").content 
    puts price 
end 

После запуска, что я получаю:

29.99 
39.95 
+0

Ах, ты прав. Я ошибочно предположил, что запрос начнется в верхней части узла, а не в документе. Проблема разрешается простым удалением «//» перед ценой. Спасибо за вашу помощь! –

+0

Исправить. Это одна из причин, по которой я предпочитаю CSS. Сляки в XPath заставляют мой мозг уставать. –