junoser 0.3.10 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/junoser/ruler.rb CHANGED
@@ -14,10 +14,9 @@ module Junoser
14
14
  str = @rule.read
15
15
  str = remove_comments(str)
16
16
  str = process_reserved_element(str)
17
- str = str.split(/\n/).map {|l| format(process_line(l)) }.join("\n")
17
+ str = str.split(/\n/).map { |l| format(process_line(l)) }.join("\n")
18
18
  end
19
19
 
20
-
21
20
  private
22
21
 
23
22
  def remove_comments(str)
@@ -27,16 +26,16 @@ module Junoser
27
26
  def process_line(str)
28
27
  return str if str =~ /^(.* do|end)$/
29
28
 
30
- str.gsub!(/("[^"]+")/) { "str(#$1)" } # "foo" -> str("foo")
29
+ str.gsub!(/("[^"]+")/) { "str(#$1)" } # "foo" -> str("foo")
31
30
 
32
- str.gsub!(/^(\s*)arg(\.as\(:\S+\))? \($/) { "#{$1}b(arg#$2," } # arg ( -> b(arg,
33
- str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+)(\.as\(:\S+\))?(,?)$/) { "#{$1}a(#$2, #$3)#$4#$5" } # str("foo") bar -> a(str("foo"), bar)
34
- str.gsub!(/^(\s*)(str\(\S+\)) (enum)?\((.*)\)(,?)$/) { "#{$1}a(#$2, #$3#$4)#$5" } # str("foo") (a | b) -> a(str("foo"), a | b)
31
+ str.gsub!(/^(\s*)arg(\.as\(:\S+\))? \($/) { "#{$1}b(arg#$2," } # arg ( -> b(arg,
32
+ str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+)(\.as\(:\S+\))?(,?)$/) { "#{$1}a(#$2, #$3)#$4#$5" } # str("foo") bar -> a(str("foo"), bar)
33
+ str.gsub!(/^(\s*)(str\(\S+\)) (enum)?\((.*)\)(,?)$/) { "#{$1}a(#$2, #$3#$4)#$5" } # str("foo") (a | b) -> a(str("foo"), a | b)
35
34
 
36
- str.gsub!(/^(\s*)(str\(\S+\)) \($/) { "#{$1}b(#$2," } # str("foo") ( -> b(str("foo"),
37
- str.gsub!(/^(\s*)(enum)?(\(.*\))(\.as\(:\S\))? \($/) { "#{$1}b(#$2#$3#$4," } # (a | b) ( -> b((a | b),
38
- str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+) \($/) { "#{$1}b(a(#$2, #$3)," } # str("foo") bar ( -> b(a(str("foo"), bar),
39
- str.gsub!(/^(\s*)(str\(\S+\)) (enum)?\((.*)\) \($/) { "#{$1}a(#$2, #$3#$4," } # str("foo") (a | b) ( -> a(str("foo"), a | b,
35
+ str.gsub!(/^(\s*)(str\(\S+\)) \($/) { "#{$1}b(#$2," } # str("foo") ( -> b(str("foo"),
36
+ str.gsub!(/^(\s*)(enum)?(\(.*\))(\.as\(:\S\))? \($/) { "#{$1}b(#$2#$3#$4," } # (a | b) ( -> b((a | b),
37
+ str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+) \($/) { "#{$1}b(a(#$2, #$3)," } # str("foo") bar ( -> b(a(str("foo"), bar),
38
+ str.gsub!(/^(\s*)(str\(\S+\)) (enum)?\((.*)\) \($/) { "#{$1}a(#$2, #$3#$4," } # str("foo") (a | b) ( -> a(str("foo"), a | b,
40
39
 
41
40
  str
42
41
  end
@@ -46,64 +45,104 @@ module Junoser
46
45
 
47
46
  str.gsub! /"groups" \(\s*s\(\s*any\s*\)\s*\)/, 'a("groups", arg, configuration)'
48
47
 
49
- %w[as-number confederation-as metric-value limit-threshold filename filter-name class-name classifier-name link-subscription per-traffic-class-bandwidth template-name].each do |key|
50
- str.gsub! %["#{key}" arg], 'arg'
51
- end
52
-
53
48
  str.gsub! '"equal-literal"', '"="'
54
49
  str.gsub! '"plus-literal"', '"+"'
55
50
  str.gsub! '"minus-literal"', '"-"'
56
51
 
57
- str.gsub!(/\((.*) \| "name"\)/) { "(#$1 | arg)" }
58
- str.gsub! '"vlan" ("all" | "vlan-name")', '"vlan" ("all" | arg)'
59
- str.gsub!(/\((.*) \| "vlan-id"\)/) { "(#$1 | arg)" }
52
+ #
53
+ # Statements can be quoted
54
+ #
60
55
  str.gsub!(/("ssh-\S+") arg/) { "#$1 (quote | arg)" }
56
+ str.gsub! '"message" arg', '"message" (quote | arg)'
61
57
  str.gsub! '"description" arg', '"description" (quote | arg)'
62
58
  str.gsub! '"as-path-prepend" arg', '"as-path-prepend" (quote | arg)'
63
- str.gsub!(/arg \| (".*")/) { "#$1 | arg" }
64
- str.gsub! '"dhcp-service" (', '("dhcp-service" | "dhcp") ('
65
59
 
66
- str.gsub!(/"inet"(.*)"inet6"/) { %["inet6"#$1"inet"] }
67
- str.gsub!(/"icmp"(.*)"icmp6"/) { %["icmp6"#$1"icmp"] }
68
- str.gsub!(/"icmp"(.*)"icmpv6"/) { %["icmpv6"#$1"icmp"] }
69
- str.gsub!(/"http"(.*)"https"/) { %["https"#$1"http"] }
70
- str.gsub!(/"snmp"(.*)"snmptrap"/) { %["snmptrap"#$1"snmp"] }
71
- %w[ccc ethernet-over-atm tcc vpls bridge].each do |encap|
72
- str.gsub!(/"ethernet"(.*)"ethernet-#{encap}"/) { %["ethernet-#{encap}"#$1"ethernet"] }
60
+ str.gsub!(/^(\s*)"as-path" arg \(\s*c\(\s*arg/) do
61
+ format(['"as-path" arg (',
62
+ ' c(',
63
+ ' quote | arg'], $1)
73
64
  end
74
- str.gsub! '"icmp6" |', '"icmp6" | "icmpv6" |'
75
- str.gsub!(/"cspf"(.*)"cspf-link"/) { %["cspf-link"#$1"cspf"] }
76
- str.gsub!(/"route-filter" (\(\s*control_route_filter_type\s*\))/) { %["route-filter" arg #{$1}.as(:oneline)] }
77
- str.gsub!(/"source-address-filter" (\(\s*control_source_address_filter_type\s*\))/) { %["source-adress-filter" arg #{$1}.as(:oneline)] }
78
65
 
79
- %w[teardown hold-time stub].each do |key|
80
- str.gsub!(/^(\s*"#{key}" \(\s*)c\(/) { "#{$1}sc(" }
66
+ str.gsub!(/^rule\(:regular_expression\) do\s*((?!end).)*\s*end/) do
67
+ <<~EOS
68
+ rule(:regular_expression) do
69
+ (quote | arg).as(:arg)
70
+ end
71
+ EOS
81
72
  end
82
- %w[file confederation].each do |key|
83
- str.gsub!(/^(\s*"#{key}" \(\s*)c\(\s*arg,/) { "#{$1}sca(" }
73
+
74
+ str.gsub!(/^rule\(:login_user_object\) do\s*arg\.as\(:arg\) \(\s*c\(\s*"full-name" arg,/) do
75
+ <<~EOS
76
+ rule(:login_user_object) do
77
+ arg.as(:arg) (
78
+ sc(
79
+ "full-name" (quote | arg),
80
+ EOS
84
81
  end
85
- %w[exact longer orlonger].each do |key|
86
- str.gsub!(/^(\s*"#{key}") arg/) { "#{$1}" }
82
+
83
+ str.gsub!(/^(\s*)"location" arg,\s*"contact" arg,/) do
84
+ format(['"location" (quote | arg),',
85
+ '"contact" (quote | arg),'], $1)
87
86
  end
88
87
 
88
+ str.gsub!(/^(\s*)"as-path" \(\s*c\(\s*"path" arg/) do
89
+ format(['"as-path" (',
90
+ ' c(',
91
+ ' "path" (quote | arg)'], $1)
92
+ end
89
93
 
90
- str.gsub!(/^(\s*)"ieee-802.3ad" \(\s*c\(\s*"lacp" \(\s*c\(/) do
91
- format(['"802.3ad" (',
92
- ' ca(',
93
- ' "lacp" (',
94
- ' c(',
95
- ' "force-up",'], $1)
94
+ str.gsub!(/^(\s*)prefix_list_items,\s*"apply-path" arg/) do
95
+ format(['"apply-path" (quote | arg),',
96
+ 'prefix_list_items'], $1)
96
97
  end
97
- str.gsub!(/^(\s*)"as-path" arg \(\s*c\(\s*arg/) do
98
- format(['"as-path" arg (',
99
- ' c(',
100
- ' quote | arg'], $1)
98
+
99
+ #
100
+ # "arg" matches anything so move to the end
101
+ #
102
+ str.gsub!(/arg \| (".*")/) { "#$1 | arg" }
103
+ str.gsub!(/^(\s*)c\(\s*arg,$/) { "#{$1}ca(" }
104
+ str.gsub!(/(rule\(:control_route_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
105
+ str.gsub!(/(rule\(:control_source_address_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
106
+ str.gsub!(/^(rule\(:trace_file_type\) do\s*)ca\(/) { "#{$1}sca(" }
107
+
108
+ str.gsub!(/^(rule\(:archive_object\) do\s*)c\(/) { "#{$1}sc(" }
109
+ str.gsub!(/^(rule\(:server_group_type\) do\s*)c\(\s*c\(\s*arg\s*\)\s*\)/) { "#{$1}s(arg, arg)" }
110
+
111
+ str.gsub!(/^(rule\(:rib_group_inet_type\) do)\s*c\(\s*arg/) do
112
+ format([$1,
113
+ ' ca(',
114
+ ' a(arg, arg)'], '')
101
115
  end
102
- str.gsub!(/^(\s*)"priority" \(\s*c\(\s*arg,\s*arg\s*\)/) do
116
+
117
+ # Fix overkill
118
+ str.gsub!(/^(\s*)"priority" \(\s*ca\(\s*arg\s*\)/) do
103
119
  format(['"priority" (',
104
120
  ' a(arg, arg)', $1])
105
121
  end
106
- str.gsub!(/^(\s*)"path" arg \(\s*c\(\s*c\(\s*"abstract",\s*c\(\s*"loose",\s*"loose-link",\s*"strict"\s*\)\s*\)\.as\(:oneline\)/) do
122
+
123
+ #
124
+ # Longer pattern first
125
+ #
126
+ # covers:
127
+ # "inet" | "inet6"
128
+ #
129
+ # and even
130
+ #
131
+ # "inet",
132
+ # "inet6"
133
+ str.gsub!(/"cspf"(.*\s*.*)"cspf-link"/) { %["cspf-link"#$1"cspf"] }
134
+ str.gsub!(/"http"(.*\s*.*)"https"/) { %["https"#$1"http"] }
135
+ str.gsub!(/"inet"(.*\s*.*)"inet6"/) { %["inet6"#$1"inet"] }
136
+ str.gsub!(/"icmp"(.*\s*.*)"icmp6"/) { %["icmp6"#$1"icmp"] }
137
+ str.gsub!(/"icmp"(.*\s*.*)"icmpv6"/) { %["icmpv6"#$1"icmp"] }
138
+ str.gsub!(/"snmp"(.*\s*.*)"snmptrap"/) { %["snmptrap"#$1"snmp"] }
139
+ str.gsub!(/"ospf"(.*\s*.*)"ospf3"/) { %["ospf3"#$1"ospf"] }
140
+
141
+ %w[ccc ethernet-over-atm tcc vpls bridge].each do |encap|
142
+ str.gsub!(/"ethernet"(.*)"ethernet-#{encap}"/) { %["ethernet-#{encap}"#$1"ethernet"] }
143
+ end
144
+
145
+ str.gsub!(/^(\s*)"path" arg \(\s*c\(\s*sc\(\s*"abstract",\s*c\(\s*"loose",\s*"loose-link",\s*"strict"\s*\)\s*\)\.as\(:oneline\)/) do
107
146
  format(['"path" arg (',
108
147
  ' c(',
109
148
  ' b(',
@@ -119,63 +158,69 @@ module Junoser
119
158
  ' )', $1])
120
159
  end
121
160
 
122
- str.gsub!(/^(\s*)c\(\s*\("default"\)\s*\)/) do
123
- format(['c(',
124
- ' ("default" | arg)',
125
- ')'], $1)
126
- end
161
+ #
162
+ # Fix .xsd: Elements without "nokeyword" flag
163
+ #
164
+ str.gsub!(/\((.*) \| "name"\)/) { "(#$1 | arg)" }
165
+ str.gsub! '"vlan" ("all" | "vlan-name")', '"vlan" ("all" | arg)'
166
+ str.gsub!(/\((.*) \| "vlan-id"\)/) { "(#$1 | arg)" }
127
167
 
128
- str.gsub!(/^rule\(:regular_expression\) do\s*((?!end).)*\s*end/) do
129
- format(['rule(:regular_expression) do',
130
- ' (quote | arg).as(:arg)',
131
- 'end'])
132
- end
133
- str.gsub!(/^rule\(:login_user_object\) do\s*arg\.as\(:arg\) \(\s*c\(\s*"full-name" arg,/) do
134
- format(['rule(:login_user_object) do',
135
- ' arg.as(:arg) (',
136
- ' sc(',
137
- ' "full-name" (quote | arg),'])
168
+ %w[filename].each do |key|
169
+ str.gsub! %["#{key}" arg], 'arg'
138
170
  end
139
171
 
140
- str.gsub!(/(rule\(:control_route_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
141
- str.gsub!(/(rule\(:control_source_address_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
142
- str.gsub!(/^(rule\(:trace_file_type\) do\s*)c\(\s*arg,/) { "#{$1}sca(" }
143
- str.gsub!(/^(rule\(:archive_object\) do\s*)c\(/) { "#{$1}sc(" }
144
- str.gsub!(/^(rule\(:server_group_type\) do\s*)c\(\s*c\(\s*arg\s*\)\s*\)/) { "#{$1}s(arg, arg)" }
145
- str.gsub!(/^(rule\(:rib_group_inet_type\) do)\s*c\(\s*arg/) do
146
- format([$1,
147
- ' ca(',
148
- ' a(arg, arg)'], '')
149
- end
172
+ # "filename" fix above leaves "arg". Move to the end
173
+ str.gsub!(/^(rule\(:esp_trace_file_type\) do\s*)c\(\s*arg,/) { "#{$1}ca(" }
150
174
 
151
- str.gsub!(/^(\s*)c\(\s*arg,$/) { "#{$1}ca(" }
175
+ # Fix .xsd: system processes dhcp is valid on some platforms
176
+ str.gsub! '"dhcp-service" (', '("dhcp-service" | "dhcp") ('
152
177
 
153
- str.gsub!(/^(\s*)"location" arg,\s*"contact" arg,/) do
154
- format(['"location" (quote | arg),',
155
- '"contact" (quote | arg),'], $1)
178
+ # Fix .xsd: "icmpv6" is also acceptable
179
+ str.gsub! '"icmp6" |', '"icmp6" | "icmpv6" |'
180
+
181
+ #
182
+ # Fix .xsd: "arg" is missing
183
+ #
184
+ str.gsub!(/"route-filter" (\(\s*control_route_filter_type\s*\))/) { %["route-filter" arg #{$1}.as(:oneline)] }
185
+ str.gsub!(/"source-address-filter" (\(\s*control_source_address_filter_type\s*\))/) { %["source-adress-filter" arg #{$1}.as(:oneline)] }
186
+ %w[file].each do |key|
187
+ str.gsub!(/^(\s*"#{key}" \(\s*)c\(\s*arg,/) { "#{$1}sca(" }
156
188
  end
157
189
 
158
- str.gsub!(/^(\s*)"as-path" \(\s*c\(\s*"path" arg/) do
159
- format(['"as-path" (',
160
- ' c(',
161
- ' "path" (quote | arg)'], $1)
190
+ # Fix .xsd: Unnecessary "arg" is added
191
+ %w[exact longer orlonger].each do |key|
192
+ str.gsub!(/^(\s*"#{key}") arg/) { "#{$1}" }
193
+ end
194
+
195
+ # Fix .xsd: "ieee-802.3ad" is invalid
196
+ str.gsub! '"ieee-802.3ad"', '"802.3ad"'
197
+
198
+ # Fix .xsd: "class-of-service interfaces all unit * classifiers exp foo"
199
+ str.gsub!(/^(\s*)sc\(\s*\("default"\)\s*\)/) do
200
+ format(['c(',
201
+ ' ("default" | arg)',
202
+ ')'], $1)
162
203
  end
163
204
 
205
+ # Fix .xsd: "from-zone" arg is also required
164
206
  str.gsub!(/^(\s*)"policy" \(\s*s\(\s*arg,\s*"to-zone-name" arg,\s*c\(\s*"policy" \(\s*policy_type\s*\)\s*\)/) do
165
207
  format(['b(s("from-zone", arg, "to-zone", arg),',
166
208
  ' b("policy", policy_type',
167
209
  ], $1)
168
210
  end
169
211
 
212
+ # Fix .xsd: "members" accepts [ foo bar ]
213
+ str.gsub! '"members" arg', '"members" any'
214
+
170
215
  str
171
216
  end
172
217
 
173
- def format(str, offset=OFFSET)
218
+ def format(str, offset = OFFSET)
174
219
  case str
175
220
  when String
176
221
  str.empty? ? '' : offset + str
177
222
  when Array
178
- str.map {|s| s.empty? ? '' : offset + s.to_s }.join("\n")
223
+ str.map { |s| s.empty? ? '' : offset + s.to_s }.join("\n")
179
224
  end
180
225
  end
181
226
 
@@ -206,7 +251,7 @@ module Junoser
206
251
 
207
252
  begin
208
253
  # .xsd doesn't include "apply-groups"
209
- if line =~ /(.*)\\s+apply-groups\\s+(\\S+|\\[.*\\])$/
254
+ if line =~ /(.*)\\s+apply-groups(-except)?\\s+(\\S+|\\[.*\\])$/
210
255
  return \$1 == 'set' ? true : parse(\$1)
211
256
  end
212
257
 
@@ -19,10 +19,12 @@ module Junoser
19
19
  @lines << l
20
20
  when /^delete /
21
21
  delete_lines delete_pattern(l.gsub(/^delete /, 'set '))
22
+ when /^activate /
23
+ delete_lines l.gsub(/^activate /, 'deactivate ')
22
24
  when /^insert (.*) before (.*)/
23
- insert_before insert_pattern("set #{$1}"), $2
25
+ insert_before "set #{$1}", $2
24
26
  when /^insert (.*) after (.*)/
25
- insert_after insert_pattern("set #{$1}"), $2
27
+ insert_after "set #{$1}", $2
26
28
  end
27
29
  end
28
30
 
@@ -70,18 +72,14 @@ module Junoser
70
72
  "(#{line}\s+)#{last_token}.*"
71
73
  end
72
74
 
73
- def insert_pattern(line)
74
- line, last_token = split_last_token(line)
75
- "(#{line})\s+#{last_token}"
76
- end
77
-
78
- def insert_before(pattern_to_insert, key_token)
79
- key_pattern = pattern_to_insert.sub(/\).*/) { ") #{key_token}" }
75
+ def insert_before(statement_to_insert, key_statement)
76
+ key_tokens = key_statement.strip.split
77
+ key_statement = (statement_to_insert.strip.split[0..-(key_tokens.size+1)] + key_tokens).join(' ')
80
78
 
81
- lines_to_insert = @lines.select { |l| l =~ /#{pattern_to_insert}/ }
82
- @lines.reject! { |l| l =~ /#{pattern_to_insert}/ }
79
+ lines_to_insert = @lines.select { |l| l.include?(statement_to_insert) }
80
+ @lines.reject! { |l| l.include?(statement_to_insert) }
83
81
 
84
- key_index = @lines.index { |l| l =~ /#{key_pattern}/ }
82
+ key_index = @lines.index { |l| l.include?(key_statement) }
85
83
  @lines.insert(key_index, lines_to_insert).flatten!
86
84
  end
87
85
 
@@ -1,3 +1,3 @@
1
1
  module Junoser
2
- VERSION = "0.3.10"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -1,13 +1,14 @@
1
1
  module Junoser
2
2
  module Xsd
3
3
  module Base
4
- attr_reader :xml
4
+ attr_reader :xml, :parent
5
5
 
6
6
  OFFSET = ' '
7
7
 
8
8
  def initialize(xml, options={})
9
9
  @xml = xml
10
10
  @depth = options[:depth] || 0
11
+ @parent = options[:parent]
11
12
  end
12
13
 
13
14
  def config
@@ -32,13 +33,13 @@ module Junoser
32
33
  ']>'].join("\n#{OFFSET*(@depth+1)}")
33
34
  end
34
35
 
35
-
36
- private
37
-
38
36
  def oneliner?
39
37
  @oneliner ||= !xml.xpath('./xsd:annotation/xsd:appinfo/flag[text()="oneliner"]').empty?
40
38
  end
41
39
 
40
+
41
+ private
42
+
42
43
  def nokeyword?
43
44
  @nokeyword ||= !xml.xpath('./xsd:annotation/xsd:appinfo/flag[text()="nokeyword"]').empty?
44
45
  end
@@ -10,9 +10,9 @@ module Junoser
10
10
  @config ||= children.map {|child|
11
11
  case child.name
12
12
  when 'element'
13
- Junoser::Xsd::Element.new(child, depth: @depth+1)
13
+ Junoser::Xsd::Element.new(child, depth: @depth+1, parent: self)
14
14
  when 'choice'
15
- Junoser::Xsd::Choice.new(child, depth: @depth+1)
15
+ Junoser::Xsd::Choice.new(child, depth: @depth+1, parent: self)
16
16
  else
17
17
  raise "ERROR: unknown element: #{child.name}"
18
18
  end
@@ -29,6 +29,10 @@ module Junoser
29
29
  format('c(', config.map(&:to_s).join(",\n"), ')')
30
30
  end
31
31
  end
32
+
33
+ def unbounded?
34
+ xml['maxOccurs'] == 'unbounded'
35
+ end
32
36
  end
33
37
  end
34
38
  end
@@ -18,9 +18,9 @@ module Junoser
18
18
  @config ||= children.map {|child|
19
19
  case child.name
20
20
  when 'sequence'
21
- Junoser::Xsd::Sequence.new(child, depth: @depth+1)
21
+ Junoser::Xsd::Sequence.new(child, depth: @depth+1, parent: self)
22
22
  when 'simpleContent'
23
- Junoser::Xsd::SimpleContent.new(child, depth: @depth+1)
23
+ Junoser::Xsd::SimpleContent.new(child, depth: @depth+1, parent: self)
24
24
  when 'attribute'
25
25
  'arg'
26
26
  else
@@ -52,7 +52,7 @@ module Junoser
52
52
  def argument
53
53
  return unless @argument
54
54
 
55
- arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1).config
55
+ arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1, parent: self).config
56
56
  raise "ERROR: argument shouldn't consist of multiple elements" if arg.size > 1
57
57
 
58
58
  if root?
@@ -16,9 +16,9 @@ module Junoser
16
16
  @config ||= children.map {|child|
17
17
  case child.name
18
18
  when 'complexType'
19
- Junoser::Xsd::ComplexType.new(child, depth: @depth+1)
19
+ Junoser::Xsd::ComplexType.new(child, depth: @depth+1, parent: self)
20
20
  when 'simpleType'
21
- Junoser::Xsd::SimpleType.new(child, depth: @depth+1)
21
+ Junoser::Xsd::SimpleType.new(child, depth: @depth+1, parent: self)
22
22
  else
23
23
  raise "ERROR: unknown element: #{child.name}"
24
24
  end
@@ -70,7 +70,7 @@ module Junoser
70
70
  when @argument.name == 'simpleType'
71
71
  'arg'
72
72
  else
73
- arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1).config
73
+ arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1, parent: self).config
74
74
  raise "ERROR: argument shouldn't consist of multiple elements" if arg.size > 1
75
75
  arg.first.to_s.strip
76
76
  end
@@ -97,6 +97,10 @@ module Junoser
97
97
 
98
98
  def documentation
99
99
  @documentation ||= xml.xpath('./xsd:annotation/xsd:documentation').text
100
+
101
+ # Translate multiline documentation into a single line to make it parsable in further processes
102
+ @documentation.gsub! /\n\s*/, ' '
103
+
100
104
  @documentation.empty? ? nil : @documentation
101
105
  end
102
106
  end
@@ -17,9 +17,9 @@ module Junoser
17
17
  @config ||= children.map {|child|
18
18
  case child.name
19
19
  when 'enumeration'
20
- Junoser::Xsd::Enumeration.new(child, depth: @depth+1)
20
+ Junoser::Xsd::Enumeration.new(child, depth: @depth+1, parent: self)
21
21
  when 'simpleType'
22
- Junoser::Xsd::SimpleType.new(child, depth: @depth+1)
22
+ Junoser::Xsd::SimpleType.new(child, depth: @depth+1, parent: self)
23
23
  when 'attribute'
24
24
  else
25
25
  raise "ERROR: unknown element: #{child.name}"