mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
f6280910f8
Rather than embedding XML and JSON support within fog-core, this is the start of extracting them to exist alongside core. That will move the responsibility to each provider to declare if they want XML or JSON services. Goal being as we move towards a modular fog this allows providers to require core and either JSON or XML gems and not pick up dependencies only required by the other.
116 lines
2.7 KiB
Ruby
116 lines
2.7 KiB
Ruby
require "nokogiri"
|
|
|
|
module Fog
|
|
module Parsers
|
|
class Base < Nokogiri::XML::SAX::Document
|
|
|
|
attr_reader :response
|
|
|
|
def initialize
|
|
reset
|
|
end
|
|
|
|
def attr_value(name, attrs)
|
|
(entry = attrs.detect {|a, v| a == name }) && entry.last
|
|
end
|
|
|
|
def reset
|
|
@response = {}
|
|
end
|
|
|
|
def characters(string)
|
|
@value ||= ''
|
|
@value << string
|
|
end
|
|
|
|
# ###############################################################################
|
|
# This is a workaround. Original implementation from Nokogiri is overwritten with
|
|
# one that does not join namespace prefix with local name.
|
|
def start_element_namespace name, attrs = [], prefix = nil, uri = nil, ns = []
|
|
start_element name, attrs
|
|
end
|
|
|
|
def end_element_namespace name, prefix = nil, uri = nil
|
|
end_element name
|
|
end
|
|
|
|
# ###############################################################################
|
|
|
|
def start_element(name, attrs = [])
|
|
@value = nil
|
|
end
|
|
|
|
def value
|
|
@value && @value.dup
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
module Fog
|
|
class ToHashDocument < Nokogiri::XML::SAX::Document
|
|
|
|
def initialize
|
|
@stack = []
|
|
end
|
|
|
|
def characters(string)
|
|
@value ||= ''
|
|
@value << string.strip
|
|
end
|
|
|
|
def end_element(name)
|
|
last = @stack.pop
|
|
if last.empty? && @value.empty?
|
|
@stack.last[name.to_sym] = ''
|
|
elsif last == {:i_nil=>"true"}
|
|
@stack.last[name.to_sym] = nil
|
|
elsif !@value.empty?
|
|
@stack.last[name.to_sym] = @value
|
|
end
|
|
@value = ''
|
|
end
|
|
|
|
def body
|
|
@stack.first
|
|
end
|
|
|
|
def response
|
|
body
|
|
end
|
|
|
|
def start_element(name, attributes = [])
|
|
@value = ''
|
|
parsed_attributes = {}
|
|
until attributes.empty?
|
|
if attributes.first.is_a?(Array)
|
|
key, value = attributes.shift
|
|
else
|
|
key, value = attributes.shift, attributes.shift
|
|
end
|
|
parsed_attributes[key.gsub(':','_').to_sym] = value
|
|
end
|
|
if @stack.last.is_a?(Array)
|
|
@stack.last << {name.to_sym => parsed_attributes}
|
|
else
|
|
data = if @stack.empty?
|
|
@stack.push(parsed_attributes)
|
|
parsed_attributes
|
|
elsif @stack.last[name.to_sym]
|
|
unless @stack.last[name.to_sym].is_a?(Array)
|
|
@stack.last[name.to_sym] = [@stack.last[name.to_sym]]
|
|
end
|
|
@stack.last[name.to_sym] << parsed_attributes
|
|
@stack.last[name.to_sym].last
|
|
else
|
|
@stack.last[name.to_sym] = {}
|
|
@stack.last[name.to_sym].merge!(parsed_attributes)
|
|
@stack.last[name.to_sym]
|
|
end
|
|
@stack.push(data)
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|