Class: CqlElm::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/measures/elm_parser.rb

Class Method Summary collapse

Class Method Details

.extract_node_type(child) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/measures/elm_parser.rb', line 61

def self.extract_node_type(child)
  ref_node = nil
  node_type = nil
  #Tries to pair the current annotation node with an elm node.
  @fields.each do |field|
    ref_node ||= @doc.at_css(field + '[localId="'+child['r']+'"]') unless child['r'].nil?
  end
  #Tries to extract the current node's type.
  node_type = ref_node['xsi:type'] unless ref_node.nil?
  node_type
end

.parse(elm_xml) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/measures/elm_parser.rb', line 7

def self.parse(elm_xml)
  ret = {
    statements: [],
    identifier: {}
  }
  @doc = Nokogiri::XML(elm_xml) {|d| d.noblanks}
  #extract library identifier data
  ret[:identifier][:id] = @doc.css("identifier").attr("id").value()
  ret[:identifier][:version] = @doc.css("identifier").attr("version").value()
  
  #extracts the fields of type "annotation" and their children.
  annotations = @doc.css("annotation")
  annotations.each do |node|
      node, define_name = parse_node(node)
      if !define_name.nil?
        node[:define_name] = define_name
        ret[:statements] << node
      end
  end
  ret
end

.parse_node(node) ⇒ Object

Recursive function that traverses the annotation tree and constructs a representation that will be compatible with the front end.



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
# File 'lib/measures/elm_parser.rb', line 31

def self.parse_node(node)
  ret = {
    children: []
  }
  define_name = nil
  node.children.each do |child|
    #Nodes with the 'a' prefix are not leaf nodes
    if child.namespace.respond_to?(:prefix) && child.namespace.prefix == 'a'
      node_type = extract_node_type(child)
      #Parses the current child recursively. child_define_name will bubble up to indicate which
      #statement is currently being traversed.
      node, child_define_name = parse_node(child)
      node[:node_type] = node_type  unless node_type.nil?
      node[:ref_id] = child['r'] unless child['r'].nil?
      define_name = child_define_name unless child_define_name.nil? 
      ret[:children] << node
    else
      if (/^define/ =~ child.to_html)
        define_name = child.to_html.split("\"")[1]
      end
      clause = {
        text: child.to_html.gsub(/\t/, "  ")
      }
      clause[:ref_id] = child['r'] unless child['r'].nil?
      ret[:children] << clause
    end
  end
  return ret, define_name
end