2013-06-14 06:02:30 -04:00
|
|
|
require "nokogiri"
|
2011-02-16 20:25:50 -05:00
|
|
|
|
2009-05-19 02:06:49 -04:00
|
|
|
module Fog
|
|
|
|
module Parsers
|
|
|
|
class Base < Nokogiri::XML::SAX::Document
|
|
|
|
|
2009-05-20 21:49:20 -04:00
|
|
|
attr_reader :response
|
2009-05-19 02:06:49 -04:00
|
|
|
|
|
|
|
def initialize
|
|
|
|
reset
|
|
|
|
end
|
|
|
|
|
2011-05-12 16:15:13 -04:00
|
|
|
def attr_value(name, attrs)
|
|
|
|
(entry = attrs.detect {|a, v| a == name }) && entry.last
|
|
|
|
end
|
|
|
|
|
2009-05-19 02:06:49 -04:00
|
|
|
def reset
|
2009-05-20 21:49:20 -04:00
|
|
|
@response = {}
|
2009-05-19 02:06:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def characters(string)
|
2011-04-13 11:58:06 -04:00
|
|
|
@value ||= ''
|
2011-05-12 16:15:13 -04:00
|
|
|
@value << string
|
2009-05-19 02:06:49 -04:00
|
|
|
end
|
|
|
|
|
2012-12-13 11:15:27 -05:00
|
|
|
# ###############################################################################
|
|
|
|
# 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
|
|
|
|
|
|
|
|
# ###############################################################################
|
|
|
|
|
2009-05-19 02:06:49 -04:00
|
|
|
def start_element(name, attrs = [])
|
2010-05-05 16:39:41 -04:00
|
|
|
@value = nil
|
2009-05-19 02:06:49 -04:00
|
|
|
end
|
|
|
|
|
2011-05-12 16:15:13 -04:00
|
|
|
def value
|
|
|
|
@value && @value.dup
|
2011-01-08 22:53:54 -05:00
|
|
|
end
|
|
|
|
|
2009-05-19 02:06:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2010-06-18 17:35:29 -04:00
|
|
|
|
|
|
|
module Fog
|
2010-06-18 18:16:07 -04:00
|
|
|
class ToHashDocument < Nokogiri::XML::SAX::Document
|
2010-06-18 17:35:29 -04:00
|
|
|
|
|
|
|
def initialize
|
|
|
|
@stack = []
|
|
|
|
end
|
|
|
|
|
|
|
|
def characters(string)
|
|
|
|
@value ||= ''
|
|
|
|
@value << string.strip
|
|
|
|
end
|
|
|
|
|
|
|
|
def end_element(name)
|
2010-06-18 17:53:35 -04:00
|
|
|
last = @stack.pop
|
2010-06-18 17:54:34 -04:00
|
|
|
if last.empty? && @value.empty?
|
2010-06-18 17:53:35 -04:00
|
|
|
@stack.last[name.to_sym] = ''
|
2010-06-17 19:58:09 -04:00
|
|
|
elsif last == {:i_nil=>"true"}
|
|
|
|
@stack.last[name.to_sym] = nil
|
2010-06-18 18:16:07 -04:00
|
|
|
elsif !@value.empty?
|
2010-06-18 17:35:29 -04:00
|
|
|
@stack.last[name.to_sym] = @value
|
|
|
|
end
|
2010-06-18 17:53:35 -04:00
|
|
|
@value = ''
|
2010-06-18 17:35:29 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def body
|
|
|
|
@stack.first
|
|
|
|
end
|
|
|
|
|
2010-06-23 16:22:20 -04:00
|
|
|
def response
|
|
|
|
body
|
|
|
|
end
|
|
|
|
|
2010-06-18 17:35:29 -04:00
|
|
|
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
|
2010-06-18 18:16:07 -04:00
|
|
|
parsed_attributes[key.gsub(':','_').to_sym] = value
|
2010-06-18 17:35:29 -04:00
|
|
|
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
|