Module: Duxml::RngChildrenRule

Includes:
LazyOx, Ox
Included in:
ChildrenRuleClass
Defined in:
lib/duxml/meta/grammar/relax_ng/children_rule.rb,
lib/duxml/meta/grammar/relax_ng/children_rule.rb

Instance Method Summary collapse

Methods included from LazyOx

#method_missing

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Duxml::LazyOx

Instance Method Details

#relaxng(parent) ⇒ Ox::Element

Returns same parent but with addition of with #statement converted into 's these are wrapped as needed in ,, or .

Parameters:

  • parent (Ox::Element) —

    parent from RelaxNG document under construction (should be )

Returns:

  • (Ox::Element) —

    same parent but with addition of with #statement converted into 's these are wrapped as needed in ,, or

Raises:

  • (Exception)


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
# File 'lib/duxml/meta/grammar/relax_ng/children_rule.rb', line 19

def relaxng(parent)
  nodes = parent.Define(name: subject)
  raise Exception if nodes.size > 1

  if nodes.first.nil?
    element_def = Element.new('element')
    element_def[:name] = subject
    define = Element.new('define')
    define[:name] = subject
    define << element_def
    parent << define
  else
    element_def = nodes.first.nodes.first
  end

  # loop through child requirements
  get_scanners.each do |scanner|
    # wrap in requirement node if needed
    operator_name = case scanner[:operator]
                      when '?' then :optional
                      when '*' then :zeroOrMore
                      when '+' then :oneOrMore
                      else nil
                    end
    if operator_name
      cur_element = Element.new(operator_name.to_s)
      element_def << cur_element
    else
      cur_element = element_def
    end

    # if child requirement has enumerated options, wrap in <choice>
    element_array = scanner[:match].source.gsub('\b','').scan(Regexp.nmtoken).flatten.keep_if do |e| !e.empty? end
    if element_array.size > 1
      choice_el = Element.new 'choice'
      cur_element << choice_el
      cur_element = choice_el
    end

    # adding enumerated options as new element defs if needed
    element_array.each do |element_name|
      existing_defs = parent.Define(name: element_name)
      raise Exception if existing_defs.size > 1
      if existing_defs.empty?
        new_def = Element.new('define')
        new_def[:name] = element_name
        child_el_def = Element.new('element')
        child_el_def[:name] = element_name
        new_def << child_el_def
        parent << new_def
      end

      if element_name == '#PCDATA'
        cur_element << Element.new('text')
      else
        ref_node = Element.new('ref')
        ref_node[:name] = element_name
        cur_element << ref_node
      end
    end # element_array.each
  end # get_scanners.each
  parent
end