Nokogiri 문서를 Ruby Hash로 변환
Nokogiri XML 문서를 해시로 변환하는 쉬운 방법이 있습니까?
Rails의 Hash.from_xml
.
이 코드를 libxml-ruby (1.1.3)와 함께 사용합니다. 나는 nokogiri를 직접 사용하지 않았지만 어쨌든 libxml-ruby를 사용한다는 것을 이해합니다. xml 요소를 루비 객체에 매핑하는 ROXML ( http://github.com/Empact/roxml/tree )도 살펴 보시기 바랍니다 . libxml 위에 빌드됩니다.
# USAGE: Hash.from_libxml(YOUR_XML_STRING)
require 'xml/libxml'
# adapted from
# http://movesonrails.com/articles/2008/02/25/libxml-for-active-resource-2-0
class Hash
class << self
def from_libxml(xml, strict=true)
begin
XML.default_load_external_dtd = false
XML.default_pedantic_parser = strict
result = XML::Parser.string(xml).parse
return { result.root.name.to_s => xml_node_to_hash(result.root)}
rescue Exception => e
# raise your custom exception here
end
end
def xml_node_to_hash(node)
# If we are at the root of the document, start the hash
if node.element?
if node.children?
result_hash = {}
node.each_child do |child|
result = xml_node_to_hash(child)
if child.name == "text"
if !child.next? and !child.prev?
return result
end
elsif result_hash[child.name.to_sym]
if result_hash[child.name.to_sym].is_a?(Object::Array)
result_hash[child.name.to_sym] << result
else
result_hash[child.name.to_sym] = [result_hash[child.name.to_sym]] << result
end
else
result_hash[child.name.to_sym] = result
end
end
return result_hash
else
return nil
end
else
return node.content.to_s
end
end
end
end
Nokogiri XML 문서를 해시로 변환하려면 다음을 수행하십시오.
require 'active_support/core_ext/hash/conversions'
hash = Hash.from_xml(nokogiri_document.to_s)
다음은 요소와 속성 모두에 대한 네임 스페이스 정보를 포함하는 강력한 해시를 만드는 훨씬 더 간단한 버전입니다.
require 'nokogiri'
class Nokogiri::XML::Node
TYPENAMES = {1=>'element',2=>'attribute',3=>'text',4=>'cdata',8=>'comment'}
def to_hash
{kind:TYPENAMES[node_type],name:name}.tap do |h|
h.merge! nshref:namespace.href, nsprefix:namespace.prefix if namespace
h.merge! text:text
h.merge! attr:attribute_nodes.map(&:to_hash) if element?
h.merge! kids:children.map(&:to_hash) if element?
end
end
end
class Nokogiri::XML::Document
def to_hash; root.to_hash; end
end
실제 모습 :
xml = '<r a="b" xmlns:z="foo"><z:a>Hello <b z:m="n" x="y">World</b>!</z:a></r>'
doc = Nokogiri::XML(xml)
p doc.to_hash
#=> {
#=> :kind=>"element",
#=> :name=>"r",
#=> :text=>"Hello World!",
#=> :attr=>[
#=> {
#=> :kind=>"attribute",
#=> :name=>"a",
#=> :text=>"b"
#=> }
#=> ],
#=> :kids=>[
#=> {
#=> :kind=>"element",
#=> :name=>"a",
#=> :nshref=>"foo",
#=> :nsprefix=>"z",
#=> :text=>"Hello World!",
#=> :attr=>[],
#=> :kids=>[
#=> {
#=> :kind=>"text",
#=> :name=>"text",
#=> :text=>"Hello "
#=> },
#=> {
#=> :kind=>"element",
#=> :name=>"b",
#=> :text=>"World",
#=> :attr=>[
#=> {
#=> :kind=>"attribute",
#=> :name=>"m",
#=> :nshref=>"foo",
#=> :nsprefix=>"z",
#=> :text=>"n"
#=> },
#=> {
#=> :kind=>"attribute",
#=> :name=>"x",
#=> :text=>"y"
#=> }
#=> ],
#=> :kids=>[
#=> {
#=> :kind=>"text",
#=> :name=>"text",
#=> :text=>"World"
#=> }
#=> ]
#=> },
#=> {
#=> :kind=>"text",
#=> :name=>"text",
#=> :text=>"!"
#=> }
#=> ]
#=> }
#=> ]
#=> }
나는 단순히 XML을 (Rails가 아닌) Hash로 변환하려고 시도하면서 이것을 발견했습니다. 나는 Nokogiri를 사용할 것이라고 생각했지만 결국 Nori를 사용하게되었습니다 .
Then my code was trival:
response_hash = Nori.parse(response)
Other users have pointed out that this does not work. I have not verified, but it seems that the parse method has been moved from the class to the instance. My code above worked at some point. New (unverified) code would be:
response_hash = Nori.new.parse(response)
Use Nokogiri to parse XML response to ruby hash. It's pretty fast.
doc = Nokogiri::XML(response_body)
Hash.from_xml(doc.to_s)
If you define something like this in your configuration:
ActiveSupport::XmlMini.backend = 'Nokogiri'
it includes a module in Nokogiri and you gain the to_hash
method.
If the node you've selected in Nokogiri consists of only one tag, you can extract the keys, values and zip them into one hash, like so:
@doc ||= Nokogiri::XML(File.read("myxmldoc.xml"))
@node = @doc.at('#uniqueID') # this works if this selects only one node
nodeHash = Hash[*@node.keys().zip(@node.values()).flatten]
See http://www.ruby-forum.com/topic/125944 for more info on Ruby array merging.
Have a look at the simple mix-in I made for the Nokogiri XML Node.
http://github.com/kuroir/Nokogiri-to-Hash
Here's a usage example:
require 'rubygems'
require 'nokogiri'
require 'nokogiri_to_hash'
html = '
<div id="hello" class="container">
<p>Hello! visit my site <a href="http://kuroir.com">Kuroir.com</a></p>
</div>
'
p Nokogiri.HTML(html).to_hash
=> [{:div=>{:class=>["container"], :children=>[{:p=>{:children=>[{:a=>{:href=>["http://kuroir.com"], :children=>[]}}]}}], :id=>["hello"]}}]
참고URL : https://stackoverflow.com/questions/1230741/convert-a-nokogiri-document-to-a-ruby-hash
'Program Tip' 카테고리의 다른 글
정당화 내용과 정렬 항목의 차이점은 무엇입니까? (0) | 2020.11.13 |
---|---|
Java에 복사 생성자가없는 이유는 무엇입니까? (0) | 2020.11.13 |
PHP에서 실시간 출력으로 프로세스 실행 (0) | 2020.11.13 |
XML 문서에 HTML 내용을 삽입 할 수 있습니까? (0) | 2020.11.13 |
unix-파일의 열 수 (0) | 2020.11.13 |