2011-03-30 3 views
1

좀 구글의 Picasa를 XML의 일부 데이터를 얻기 위해 노력하고, 그리고 약간의 문제를 데 .. 여기 nokogiri를 사용하여 google picasa api xml - namespacing 문제를 구문 분석 하시겠습니까?

는 (하나의 항목을 포함) 실제 XML입니다 : 기본적으로 http://pastie.org/1736008

을 나는 것 이상적으로 내가하고 싶은 무엇의에서는 gphoto 속성의 몇 가지를 수집하고자 :

doc.xpath('//entry').map do |entry| 
    {:id => entry.children['gphoto:id'], 
    :thumb => entry.children['gphoto:thumbnail'], 
    :name => entry.children['gphoto:name'], 
    :count => entry.children['gphoto:numphotos']} 
end 

그러나, 이것은 내가 항목의 아이들을 검토 할 때, 나는 그렇지, 사실 ... 작동하지 않습니다 어떤 'gphoto : xxx'도 전혀 볼 수 없다. 그래서 나는 어떻게해야하는지 혼란 스럽다. 그들을 찾아라.

감사합니다.

답변

2

다음은 nokogiri를 사용하여 예제 XML에서 gphoto 요소를 추출하는 작업 코드입니다.

#!/usr/bin/env ruby 
require 'rubygems' 
require 'nokogiri' 
content = File.read('input.xml') 
doc = Nokogiri::XML(content) {|config| 
      config.options = Nokogiri::XML::ParseOptions::STRICT 
     } 

hashes = doc.xpath('//xmlns:entry').map do |entry| 
    { 
    :id => entry.xpath('gphoto:id').inner_text, 
    :thumb => entry.parent.xpath('gphoto:thumbnail').inner_text, 
    :name => entry.xpath('gphoto:name').inner_text, 
    :count => entry.xpath('gphoto:numphotos').inner_text 
    } 
end 

puts hashes.inspect 

# yields: 
# 
# [{:count=>"37", :name=>"Melody19Months", :thumb=>"http://lh3.ggpht.com/_Viv8WkAChHU/AAAAAAAAAAA/AAAAAAAAAAA/pNuu5PgnP1Y/s64-c/soopingsaw.jpg", :id=>"5582695833628950881"}] 

주 : 당신의 요점의 샘플 XML을 닫는 "공급"태그를 필요

  1. . 고정 here.
  2. 항목 요소를 찾으려면 xpath 표현식에서 "항목"이 아닌 "xmlns : entry"라는 네임 스페이스 접두어를 사용해야합니다. 후자 (원래 코드에서 사용됨)는 이 아니며 요소를 찾습니다. null 네임 스페이스의 요소를 찾고 있지만 예제에서는 피드 요소에 지정된 기본 네임 스페이스를 상속합니다. 애런 패터슨 (Aaron Patterson)은 문제의 소개 (Nokogiri 중심) here을 작성했으며 또 다른 here이 있습니다.
  3. 요소 gphoto : thumbnail은 피드 요소의 하위 요소이며 이 아니며 각 항목의입니다. 원래 예제의 디자인을 유지하면서 작은 (해킹 된) 조정을했지만, 까지 피드 당이 요소의 값을 한 번만 찾는 것이 좋습니다. (아마도 나중에 항목 해시를 채우는 것이 좋습니다. 실제로 각각 사본을 보관할 필요가 있음).
  4. Nokogiri를 엄격하게 구성하는 것은 실제로는 필요하지 않지만 문제를 조기에 발견하는 데 약간의 도움을 얻는 것이 좋습니다.
0

그런 다음 gphoto 네임 스페이스 노드를 추출하기 위해 각각의 내부 찾습니다 entry 노드를 검색 할 수 있습니다

모든 //entry/gphoto:* 메모를 반환
require 'nokogiri' 

doc = Nokogiri::XML(open('./test.xml')) 
hashes = doc.search('//xmlns:entry').map do |entry| 
    h = {} 
    entry.search("*[namespace-uri()='http://schemas.google.com/photos/2007']").each do |gphoto| 
    h[gphoto.name] = gphoto.text 
    end 
    h 
end 

require 'ap' 
ap hashes 
# >> [ 
# >>  [0] { 
# >>      "id" => "5582695833628950881", 
# >>      "name" => "Melody19Months", 
# >>     "location" => "", 
# >>     "access" => "public", 
# >>     "timestamp" => "1299649559000", 
# >>     "numphotos" => "37", 
# >>      "user" => "soopingsaw", 
# >>     "nickname" => "sooping", 
# >>   "commentingEnabled" => "true", 
# >>    "commentCount" => "0" 
# >>  } 
# >> ] 

. 당신이 특정 사람을 원하는 경우에 당신은 당신이 원하는 무엇을 필터링 할 수 있습니다

require 'nokogiri' 

doc = Nokogiri::XML(open('./test.xml')) 
hashes = doc.search('//xmlns:entry').map do |entry| 
    h = {} 
    entry.search("*[namespace-uri()='http://schemas.google.com/photos/2007']").each do |gphoto| 
    h[gphoto.name] = gphoto.text if (%w[id thumbnail name numphotos].include?(gphoto.name)) 
    end 
    h 
end 

require 'ap' 
ap hashes 

# >> [ 
# >>  [0] { 
# >>    "id" => "5582695833628950881", 
# >>    "name" => "Melody19Months", 
# >>   "numphotos" => "37" 
# >>  } 
# >> ] 

공지 사항을 gphoto:thumbnail에 액세스하기위한 시도가 발생 원래의 질문에, 그러나 //element/gphoto:thumbnails에 대한 일치하는 노드가 없다는 것을, 그것을 찾을 수 없습니다 수 .

네임 스페이스를 사용하여 검색을 작성하는 또 다른 방법은 다음과 같습니다

require 'nokogiri' 

doc = Nokogiri::XML(open('./test.xml')) 
hashes = doc.search('//xmlns:entry').map do |entry| 
    h = {} 
    entry.search("*").each do |gphoto| 
    h[gphoto.name] = gphoto.text if (
     (gphoto.namespace.prefix=='gphoto') && 
     (%w[id thumbnail name numphotos].include?(gphoto.name)) 
    ) 
    end 
    h 
end 

require 'ap' 
ap hashes 

# >> [ 
# >>  [0] { 
# >>    "id" => "5582695833628950881", 
# >>    "name" => "Melody19Months", 
# >>   "numphotos" => "37" 
# >>  } 
# >> ] 

이 오히려 XPath를 사용하는 것보다, 각 노드의 네임 스페이스 속성을보고 노코 기리를 묻는 데요.

관련 문제