Class: Treat::Workers::Formatters::Unserializers::XML

Inherits:
Object
  • Object
show all
Defined in:
lib/treat/workers/formatters/unserializers/xml.rb

Overview

Unserialization of entities stored in XML format.

Class Method Summary collapse

Class Method Details

.revive(type, value, id) ⇒ Object



108
109
110
111
# File 'lib/treat/workers/formatters/unserializers/xml.rb', line 108

def self.revive(type, value, id)
  klass = Treat::Entities.const_get(type.cc)
  klass.new(value, id)
end

.unserialize(document, options = {}) ⇒ Object

Unserialize an entity stored in XML format.

Options: none.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/treat/workers/formatters/unserializers/xml.rb', line 9

def self.unserialize(document, options = {})
  # Read in the XML file.
  xml = File.read(document.file)
  xml.gsub!('<treat>', '')
  xml.gsub!('</treat>', '')
  xml_reader = Nokogiri::XML::Reader.from_memory(xml)
  current_element = nil
  previous_depth = 0

  # Read the XML file entity by entity.
  while xml_reader.read
    # The depth in the XML tree.
    current_depth = xml_reader.depth
    # If we are at the end of the children stack, pop up.
    if previous_depth > current_depth && current_depth != 0
      current_element = current_element.parent
    end
    # If an end element has been reached,
    # change the depth and pop up on next
    # iteration.
    if xml_reader.node_type ==
      Nokogiri::XML::Reader::TYPE_END_ELEMENT
      previous_depth = current_depth
      next
    end

    id = nil; value = ''
    attributes = {}
    edges = []
    
    unless xml_reader.attributes.size == 0
      xml_reader.attributes.each_pair do |k,v|
        if k == 'id'
          id = v.to_i
        elsif k == 'edges'
          a = v.split('--')
          a.each do |b|
            c = b.split(';')
            c.each do |dep|
              vals = []
              dep.split(',').each do |name_val|
                name_val = name_val[0..-2] if name_val[-1] == '}'
                d =  name_val.split(':')[1]
                vals << d.strip if d
              end

              target, type, directed, direction = *vals
              edges << [
                target.to_i,
                type,
                (directed == 'true' ? true : false),
                direction.to_i
              ]
            end
          end
        elsif k == 'value'
          value = v
        else
          v = v[1..-1].intern if v[0] == ':'
          v = ":".intern if v == :''
          v = v.to_i if v =~ /^[0-9]*$/
          v = v.to_f if v =~ /^[0-9\.]*$/
          v = false if v == 'false'
          v = true if v == 'true'
          attributes[k.intern] = v
        end
      end
    end

    current_value = ''
    type = xml_reader.name.intern

    if Treat.core.entities.list.include?(type)
      if !current_element
        current_element = self.revive(type, current_value, id)
      else
        current_element = current_element <<
        self.revive(type, current_value, id)
      end
      current_element.features = attributes
      current_element.features = attributes
      edges.each do |edge|
        target, type, directed, direction = *edge
        current_element.link(target, type, directed, direction)
      end
    else
      current_value = xml_reader.value ?
      xml_reader.value.strip : ''
      if current_value && current_value != ''
        current_element.value = current_value
      end
    end

    previous_depth = current_depth
  end
  document << current_element
  document
end