require 'nokogiri' module VER module Plist class XML def initialize(xml) @doc = Nokogiri(xml) @plist = {} @parsed = nil end def parse @parsed || parse! end def parse! dict = @doc.at('/plist/dict') if dict @parsed = handle_dict(dict) else raise ArgumentError, 'This is no XML plist' end end def handle_array(array) out = [] key = nil array.children.each do |child| child_name = child.name next if child_name == 'text' out.push( case child_name when 'key' raise 'No key allows in array' when 'array'; handle_array(child) when 'dict'; handle_dict(child) when 'false'; false when 'integer', 'real'; child.inner_text.to_i when 'string'; child.inner_text when 'true'; true else # $unhandled[child_name] << child raise "%p: %p is not handled" % [child_name, child] end ) end out end def handle_dict(dict) out = {} key = nil dict.children.each do |child| child_name = child.name case child_name when 'key'; key = child.inner_text when 'text' # ignore else raise 'No key given' unless key out[key] = case child_name when 'array'; handle_array(child) when 'dict'; handle_dict(child) when 'false'; false when 'integer', 'real'; child.inner_text.to_i when 'string'; child.inner_text when 'true'; true else # $unhandled[child_name] << child raise "%p: %p is not handled" % [child_name, child] end key = nil end end out end def to_yaml parse.to_yaml end def to_json parse.to_json end def to_hash parse end end module_function def parse_xml(filename) XML.new(File.read(filename)).parse end end end