2009-08-23 2 views
1

Хорошо, переключение с рабочего Hpricot на Libxml-ruby из-за скорости и ну, исчезновение _why, некоторое время посмотрело на Nokogiri, но решило посмотреть на Libxml-ruby на скорость и долговечность. Должно быть, я что-то отсутствует основной, но то, что им пытаются сделать, это не работает, вот мой XML строка:libxml-ruby синтаксический анализ ПОМОЩЬ

<?xml version="1.0" encoding="utf-8" ?> 
<feed> 
    <title type="xhtml"></title> 
    <entry xmlns="http://www.w3.org/2005/Atom"> 
    <id>urn:publicid:xx.xxx:xxxxxx</id> 
    <title>US--xxx-xxxxx</title> 
    <updated>2009-08-19T15:49:51.103Z</updated> 
    <published>2009-08-19T15:44:48Z</published> 
    <author> 
     <name>XX</name> 
    </author> 
    <rights>blehh</rights> 
    <content type="text/xml"> 
     <nitf> 
     <head> 
      <docdata> 
      <doc-id regsrc="XX" /> 
      <date.issue norm="20090819T154448Z" /> 
      <ed-msg info="Eds:" /> 
      <doc.rights owner="xx" agent="hxx" type="none" /> 
      <doc.copyright holder="xx" year="2009" /> 
      </docdata> 
     </head> 
     <body> 
      <body.head> 
      <hedline> 
       <hl1 id="headline">headline</hl1> 
       <hl2 id="originalHeadline">blah blah</hl2> 
      </hedline> 
      <byline>john doe<byttl>staffer</byttl></byline> 
      <distributor>xyz</distributor> 
      <dateline> 
       <location>foo</location> 
      </dateline> 
      </body.head> 
      <body.content> 
      <block id="Main"> 
       story content here 
      </block> 
      </body.content> 
      <body.end /> 
     </body> 
     </nitf> 
    </content> 
    </entry> 
</feed> 

существует около 150 таких записей из комбикорма.

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

Этот небольшой фрагмент кода показывает, что им даже не получать записи:

parser = XML::Parser.string(file) 
doc = parser.parse 
entries = doc.find('//entry') 
puts entries.size 
entries.each do |node| 
    puts node.inspect 
end 

Любые идеи? Я просмотрел документы и не смог найти простой здесь XML-файл, и вот примеры вывода x, y, z. Это должно быть довольно просто.

ответ

1

Nokogiri доказал свою скорость и долговечность, так что вот несколько примеров того, как обращаться с пространствами имен в образце XML. Я использовал Nokogiri для большого агрегатора RDF/RSS/Atom, который ежедневно обрабатывал тысячи каналов, используя что-то похожее на это, чтобы захватить поля, которые я хотел, прежде чем вставлять их в базу данных.

require 'nokogiri' 

doc = Nokogiri::XML(file) 
namespace = {'xmlns' => 'http://www.w3.org/2005/Atom'} 

entries = [] 
doc.search('//xmlns:entry', namespace).each do |_entry| 

    entry_hash = {} 

    %w[title updated published author].each do |_attr| 
    entry_hash[_attr.to_sym] = _entry.at('//xmlns:' << _attr, namespace).text.strip 
    end 

    entry_hash[:headlines] = _entry.search('xmlns|hedline > hl1, xmlns|hedline > hl2', namespace).map{ |n| n.text.strip } 
    entry_hash[:body]  = _entry.at('//xmlns:body.content', namespace).text.strip 
    entry_hash[:title]  = _entry.at('//xmlns:title', namespace).text 

    entries << entry_hash 
end 

require 'pp' 
pp entries 
# >> [{:title=>"US--xxx-xxxxx", 
# >> :updated=>"2009-08-19T15:49:51.103Z", 
# >> :published=>"2009-08-19T15:44:48Z", 
# >> :author=>"XX", 
# >> :headlines=>["headline", "blah blah"], 
# >> :body=>"story content here"}] 

И CSS, и XPath в Нокигири могут обрабатывать пространства имен. Nokogiri упростил бы их использование, захватив все пространства имен, определенные в корневом узле, но в этом примере XML пространство имен определено в узле записи, заставляя нас делать это вручную.

Я перешел на нотацию CSS для заголовков, просто чтобы показать, как их выполнять. Для удобства Nokogiri обычно допускает подстановочное пространство имен для CSS, если бы оно могло найти объявление пространства имен, которое упростило бы аксессуар до '|headline > hl1' для узла hl1.

+0

Я забыл вернуться к этой теме, но да, я сделал что-то подобное Tin – initialized

0

Я подозреваю, что у вас возникли проблемы из-за пропусков на пространствах имен в вашей находке. Если вы посмотрите на xpath documentation for libxml-ruby, у них есть довольно интересные примеры. В частности, ваша находка должна быть похожа на записи = doc.find ('// atom: entry', 'atom: http://www.w3.org/2005/Atom'), которые должным образом отформатированы.

Смежные вопросы