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



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/measures/elm_parser.rb', line 67

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



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

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.



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

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]
        # Modify special characters back in the the define_name
        @html_hash.each { |k,v| define_name.gsub!(k.to_s, v) }
      end
      clause_text = child.to_html.gsub(/\t/, "  ")
      # Modify special characters back in the clause text
      @html_hash.each { |k,v| clause_text.gsub!(k.to_s, v) }
      clause = {
        text: clause_text
      }
      clause[:ref_id] = child['r'] unless child['r'].nil?
      ret[:children] << clause
    end
  end
  return ret, define_name
end