junoser 0.3.10 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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}"