Module: RightDevelop::Parsers::XmlPostParser

Included in:
SaxParser
Defined in:
lib/right_develop/parsers/xml_post_parser.rb

Class Method Summary collapse

Class Method Details

.remove_nesting(xml_object) ⇒ Array or Hash

Parses a rubified XML hash/array, removing the top level xml tag, along with any arrays encoded with singular/plural for parent/child nodes. Intended to allow for one set of code for validating JSON or XML responses.

Examples:

Initial XML:
<top_level>
 <arrays>
   <array item1="one" item2="two"/>
   <array item3="three" item4="four"/>
 </arrays>
</top_level>

Before removing nesting, after initial parsing:
{
  'top_level' => {
    'arrays' => {
     'array' => [
       {'item1' => 'one', 'item2' => 'two'},
       {'item3' => 'three', 'item4' => 'four'}
     ]
    }
  }
}

After removing nesting:
{
  'arrays' => [
    {'item1' => 'one', 'item2' => 'two'},
    {'item3' => 'three', 'item4' => 'four'}
  ]
}

Parameters:

  • xml_object (Array or Hash)

    parsed XML object, such as from Parser::Sax.parse.

Returns:

  • (Array or Hash)

    returns a ruby Array or Hash with top level xml tags removed, as well as any extra XML encoded array tags.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/right_develop/parsers/xml_post_parser.rb', line 47

def self.remove_nesting(xml_object)
  unless AVAILABLE
    raise NotImplementedError, "#{self.name} is unavailable on this system because libxml-ruby and/or active_support are not installed"
  end

  if xml_object.length != 1 || (!xml_object.is_a?(Hash) && !xml_object.is_a?(Array))
    raise ArgumentError, "xml_object format doesn't have a single top level entry"
  end
  if !xml_object.is_a?(Hash)
    raise TypeError, "xml_object object doesn't seem to be a Hash or an Array"
  end
  xml_object = deep_clone(xml_object)

  #if root & children are the same base word, get rid of both layers
  root_key       = xml_object.keys[0]
  root_child     = xml_object[xml_object.first[0]]
  if root_child.respond_to?(:keys)
    root_child_key = root_child.keys[0]
  else
    root_child_key = nil
  end

  #remove root key
  xml_object = xml_object[xml_object.first[0]]

  #remove extra root child key
  if root_key.singularize == root_child_key
    # Ensure object is an array (like JSON responses)
    xml_object = [xml_object[xml_object.first[0]]].flatten
  elsif !xml_object
     # Degenerate case where nothing was contained by parent node
     # (i.e. no resources were actually returned)
    xml_object = []
  end

  remove_nesting_node(xml_object)
  return xml_object
end