xsdvi 1.0.0

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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +30 -0
  3. data/README.adoc +317 -0
  4. data/exe/xsdvi +6 -0
  5. data/lib/xsdvi/cli.rb +163 -0
  6. data/lib/xsdvi/svg/generator.rb +93 -0
  7. data/lib/xsdvi/svg/symbol.rb +234 -0
  8. data/lib/xsdvi/svg/symbols/all.rb +46 -0
  9. data/lib/xsdvi/svg/symbols/any.rb +59 -0
  10. data/lib/xsdvi/svg/symbols/any_attribute.rb +58 -0
  11. data/lib/xsdvi/svg/symbols/attribute.rb +64 -0
  12. data/lib/xsdvi/svg/symbols/choice.rb +46 -0
  13. data/lib/xsdvi/svg/symbols/element.rb +91 -0
  14. data/lib/xsdvi/svg/symbols/field.rb +42 -0
  15. data/lib/xsdvi/svg/symbols/key.rb +46 -0
  16. data/lib/xsdvi/svg/symbols/keyref.rb +49 -0
  17. data/lib/xsdvi/svg/symbols/loop.rb +35 -0
  18. data/lib/xsdvi/svg/symbols/schema.rb +42 -0
  19. data/lib/xsdvi/svg/symbols/selector.rb +42 -0
  20. data/lib/xsdvi/svg/symbols/sequence.rb +48 -0
  21. data/lib/xsdvi/svg/symbols/unique.rb +46 -0
  22. data/lib/xsdvi/tree/builder.rb +31 -0
  23. data/lib/xsdvi/tree/element.rb +62 -0
  24. data/lib/xsdvi/utils/resource_loader.rb +21 -0
  25. data/lib/xsdvi/utils/width_calculator.rb +23 -0
  26. data/lib/xsdvi/utils/writer.rb +29 -0
  27. data/lib/xsdvi/version.rb +5 -0
  28. data/lib/xsdvi/xsd_handler.rb +323 -0
  29. data/lib/xsdvi.rb +30 -0
  30. data/resources/svg/defined_symbols.svg +9 -0
  31. data/resources/svg/doctype.txt +1 -0
  32. data/resources/svg/menu_buttons.svg +7 -0
  33. data/resources/svg/script.js +265 -0
  34. data/resources/svg/style.css +29 -0
  35. data/resources/svg/style.html +3 -0
  36. data/resources/svg/style.xml +1 -0
  37. data/resources/svg/svg_end.txt +1 -0
  38. data/resources/svg/svg_start.txt +1 -0
  39. data/resources/svg/title.txt +1 -0
  40. data/resources/svg/xml_declaration.xml +1 -0
  41. metadata +113 -0
@@ -0,0 +1,323 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module Xsdvi
6
+ # Handles XSD parsing and tree building
7
+ class XsdHandler
8
+ XSD_NAMESPACE = "http://www.w3.org/2001/XMLSchema"
9
+
10
+ attr_accessor :root_node_name, :one_node_only
11
+ attr_reader :builder, :schema_namespace
12
+
13
+ def initialize(builder)
14
+ @builder = builder
15
+ @stack = []
16
+ @root_node_name = nil
17
+ @one_node_only = false
18
+ @schema_namespace = nil
19
+ end
20
+
21
+ def process_file(file_path)
22
+ doc = Nokogiri::XML(File.read(file_path))
23
+ process_model(doc)
24
+ end
25
+
26
+ def process_model(doc)
27
+ return unless doc
28
+
29
+ # Extract target namespace
30
+ schema_node = doc.at_xpath("/xs:schema", "xs" => XSD_NAMESPACE)
31
+ @schema_namespace = schema_node["targetNamespace"] if schema_node
32
+
33
+ # Create schema symbol when no root node specified (matches Java line 65-68)
34
+ if root_node_name.nil?
35
+ symbol = SVG::Symbols::Schema.new
36
+ builder.set_root(symbol)
37
+ end
38
+
39
+ process_element_declarations(doc)
40
+
41
+ # Level up after processing all elements (matches Java line 71-73)
42
+ builder.level_up if root_node_name.nil?
43
+ end
44
+
45
+ def get_elements_names(doc)
46
+ elements = doc.xpath("//xs:schema/xs:element", "xs" => XSD_NAMESPACE)
47
+ elements.filter_map { |elem| elem["name"] }
48
+ end
49
+
50
+ def set_schema_namespace(doc, element_name)
51
+ elements = doc.xpath("//xs:schema/xs:element", "xs" => XSD_NAMESPACE)
52
+ elements.each do |elem|
53
+ if elem["name"] == element_name
54
+ @schema_namespace = schema_node = doc.at_xpath("/xs:schema",
55
+ "xs" => XSD_NAMESPACE)
56
+ @schema_namespace = schema_node["targetNamespace"] if schema_node
57
+ break
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def process_element_declarations(doc)
65
+ elements = doc.xpath("//xs:schema/xs:element", "xs" => XSD_NAMESPACE)
66
+
67
+ elements.each do |elem|
68
+ name = elem["name"]
69
+ is_root = name == root_node_name
70
+ if is_root || root_node_name.nil?
71
+ process_element_declaration(elem, nil,
72
+ is_root)
73
+ end
74
+ end
75
+ end
76
+
77
+ def process_element_declaration(elem_node, cardinality, is_root)
78
+ name = elem_node["name"]
79
+ elem_namespace = elem_node["namespace"]
80
+ elem_node["ref"]
81
+ type_attr = elem_node["type"]
82
+ nillable = elem_node["nillable"] == "true"
83
+ abstract = elem_node["abstract"] == "true"
84
+
85
+ symbol = SVG::Symbols::Element.new
86
+ symbol.name = name
87
+
88
+ # Set namespace if different from schema namespace (matches Java line 228-231)
89
+ if elem_namespace && elem_namespace != schema_namespace
90
+ symbol.namespace = elem_namespace
91
+ elsif schema_namespace && schema_namespace != elem_namespace
92
+ # Show schema namespace on element when element doesn't override it
93
+ symbol.namespace = schema_namespace
94
+ end
95
+
96
+ # Get type string (matches Java getTypeString logic)
97
+ symbol.type = get_type_string(elem_node, type_attr)
98
+ symbol.cardinality = cardinality
99
+ symbol.nillable = nillable
100
+ symbol.abstract = abstract
101
+ symbol.description = extract_documentation(elem_node)
102
+ symbol.start_y_position = 20 if is_root && one_node_only
103
+
104
+ # Set root or append child (matches Java line 241-245)
105
+ if is_root
106
+ builder.set_root(symbol)
107
+ else
108
+ builder.append_child(symbol)
109
+ end
110
+
111
+ # Check for loops (matches Java line 247-250)
112
+ if process_loop?(elem_node)
113
+ builder.level_up
114
+ return
115
+ end
116
+
117
+ @stack.push(elem_node)
118
+
119
+ # Skip processing children if stack size > 1 and oneNodeOnly (matches Java line 253-260)
120
+ unless @stack.size > 1 && one_node_only
121
+ # Check if element has inline complexType
122
+ complex_type = elem_node.at_xpath("xs:complexType",
123
+ "xs" => XSD_NAMESPACE)
124
+ if complex_type
125
+ process_complex_type_node(complex_type)
126
+ elsif !type_attr
127
+ # No type means anyType - expand it
128
+ process_any_type_default
129
+ elsif type_attr == "anyType"
130
+ process_any_type_default
131
+ end
132
+ end
133
+
134
+ @stack.pop
135
+ builder.level_up
136
+ end
137
+
138
+ def get_type_string(elem_node, type_attr)
139
+ return "type: #{type_attr}" if type_attr
140
+
141
+ # Check for inline simpleType or complexType
142
+ complex_type = elem_node.at_xpath("xs:complexType", "xs" => XSD_NAMESPACE)
143
+ simple_type = elem_node.at_xpath("xs:simpleType", "xs" => XSD_NAMESPACE)
144
+
145
+ return nil if complex_type # Anonymous complex type
146
+
147
+ if simple_type
148
+ return "base: #{simple_type.at_xpath('xs:restriction',
149
+ 'xs' => XSD_NAMESPACE)['base']}"
150
+ end
151
+
152
+ "type: anyType" # Default
153
+ end
154
+
155
+ def process_any_type_default
156
+ # anyType default content model: sequence containing 0..unbounded any and anyAttribute
157
+ symbol = SVG::Symbols::Sequence.new
158
+ symbol.cardinality = nil
159
+ builder.append_child(symbol)
160
+
161
+ # Add any element
162
+ any_symbol = SVG::Symbols::Any.new
163
+ any_symbol.namespace = "any NS"
164
+ any_symbol.process_contents = SVG::Symbol::PC_LAX
165
+ any_symbol.cardinality = "0..∞"
166
+ builder.append_child(any_symbol)
167
+ builder.level_up
168
+
169
+ builder.level_up
170
+
171
+ # Add anyAttribute
172
+ any_attr_symbol = SVG::Symbols::AnyAttribute.new
173
+ any_attr_symbol.namespace = "any NS"
174
+ any_attr_symbol.process_contents = SVG::Symbol::PC_LAX
175
+ builder.append_child(any_attr_symbol)
176
+ builder.level_up
177
+ end
178
+
179
+ def process_complex_type_node(complex_type_node)
180
+ # Process particles (sequence/choice/all)
181
+ sequence = complex_type_node.at_xpath("xs:sequence",
182
+ "xs" => XSD_NAMESPACE)
183
+ process_sequence(sequence, nil) if sequence
184
+
185
+ choice = complex_type_node.at_xpath("xs:choice", "xs" => XSD_NAMESPACE)
186
+ process_choice(choice, nil) if choice
187
+
188
+ all_node = complex_type_node.at_xpath("xs:all", "xs" => XSD_NAMESPACE)
189
+ process_all(all_node, nil) if all_node
190
+
191
+ # Process attributes
192
+ attributes = complex_type_node.xpath("xs:attribute",
193
+ "xs" => XSD_NAMESPACE)
194
+ attributes.each { |attr| process_attribute(attr) }
195
+
196
+ # Process attribute wildcard
197
+ any_attr = complex_type_node.at_xpath("xs:anyAttribute",
198
+ "xs" => XSD_NAMESPACE)
199
+ process_any_attribute(any_attr) if any_attr
200
+ end
201
+
202
+ def process_sequence(sequence_node, cardinality)
203
+ card = cardinality || get_cardinality(sequence_node)
204
+ symbol = SVG::Symbols::Sequence.new
205
+ symbol.cardinality = card
206
+ symbol.description = extract_documentation(sequence_node)
207
+ builder.append_child(symbol)
208
+
209
+ # Process child elements
210
+ sequence_node.xpath("xs:element", "xs" => XSD_NAMESPACE).each do |elem|
211
+ process_element_declaration(elem, get_cardinality(elem), false)
212
+ end
213
+
214
+ # Process any
215
+ sequence_node.xpath("xs:any", "xs" => XSD_NAMESPACE).each do |any|
216
+ process_any(any)
217
+ end
218
+
219
+ builder.level_up
220
+ end
221
+
222
+ def process_choice(choice_node, cardinality)
223
+ card = cardinality || get_cardinality(choice_node)
224
+ symbol = SVG::Symbols::Choice.new
225
+ symbol.cardinality = card
226
+ symbol.description = extract_documentation(choice_node)
227
+ builder.append_child(symbol)
228
+
229
+ # Process child elements
230
+ choice_node.xpath("xs:element", "xs" => XSD_NAMESPACE).each do |elem|
231
+ process_element_declaration(elem, get_cardinality(elem), false)
232
+ end
233
+
234
+ builder.level_up
235
+ end
236
+
237
+ def process_all(all_node, cardinality)
238
+ card = cardinality || get_cardinality(all_node)
239
+ symbol = SVG::Symbols::All.new
240
+ symbol.cardinality = card
241
+ symbol.description = extract_documentation(all_node)
242
+ builder.append_child(symbol)
243
+
244
+ # Process child elements
245
+ all_node.xpath("xs:element", "xs" => XSD_NAMESPACE).each do |elem|
246
+ process_element_declaration(elem, get_cardinality(elem), false)
247
+ end
248
+
249
+ builder.level_up
250
+ end
251
+
252
+ def process_any(any_node)
253
+ symbol = SVG::Symbols::Any.new
254
+ namespace = any_node["namespace"]
255
+ symbol.namespace = namespace || "any NS"
256
+ process_contents = any_node["processContents"]
257
+ symbol.process_contents = case process_contents
258
+ when "skip" then SVG::Symbol::PC_SKIP
259
+ when "lax" then SVG::Symbol::PC_LAX
260
+ when "strict" then SVG::Symbol::PC_STRICT
261
+ else SVG::Symbol::PC_LAX # Default is lax for anyType
262
+ end
263
+ symbol.cardinality = get_cardinality(any_node)
264
+ symbol.description = extract_documentation(any_node)
265
+ builder.append_child(symbol)
266
+ builder.level_up
267
+ end
268
+
269
+ def process_attribute(attr_node)
270
+ symbol = SVG::Symbols::Attribute.new
271
+ symbol.name = attr_node["name"]
272
+ namespace = attr_node["namespace"]
273
+ symbol.namespace = namespace if namespace && namespace != schema_namespace
274
+ symbol.type = attr_node["type"] ? "type: #{attr_node['type']}" : nil
275
+ symbol.required = attr_node["use"] == "required"
276
+ symbol.description = extract_documentation(attr_node)
277
+
278
+ builder.append_child(symbol)
279
+ builder.level_up
280
+ end
281
+
282
+ def process_any_attribute(any_attr_node)
283
+ symbol = SVG::Symbols::AnyAttribute.new
284
+ namespace = any_attr_node["namespace"]
285
+ symbol.namespace = namespace || "any NS"
286
+ process_contents = any_attr_node["processContents"]
287
+ symbol.process_contents = case process_contents
288
+ when "skip" then SVG::Symbol::PC_SKIP
289
+ when "lax" then SVG::Symbol::PC_LAX
290
+ when "strict" then SVG::Symbol::PC_STRICT
291
+ else SVG::Symbol::PC_LAX # Default is lax for anyType
292
+ end
293
+ symbol.description = extract_documentation(any_attr_node)
294
+ builder.append_child(symbol)
295
+ builder.level_up
296
+ end
297
+
298
+ def process_loop?(elem_node)
299
+ @stack.any?(elem_node)
300
+ end
301
+
302
+ def get_cardinality(node)
303
+ min_occurs = node["minOccurs"]&.to_i || 1
304
+ max_occurs = node["maxOccurs"]
305
+
306
+ return nil if min_occurs == 1 && (max_occurs.nil? || max_occurs == "1")
307
+
308
+ if max_occurs == "unbounded"
309
+ "#{min_occurs}..∞"
310
+ elsif max_occurs
311
+ "#{min_occurs}..#{max_occurs}"
312
+ end
313
+ end
314
+
315
+ def extract_documentation(node)
316
+ docs = node.xpath(
317
+ ".//xs:annotation/xs:documentation",
318
+ "xs" => XSD_NAMESPACE,
319
+ )
320
+ docs.map(&:text).map { |text| text.gsub(/\n[ \t]+/, "\n") }
321
+ end
322
+ end
323
+ end
data/lib/xsdvi.rb ADDED
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "xsdvi/version"
4
+ require_relative "xsdvi/cli"
5
+ require_relative "xsdvi/xsd_handler"
6
+ require_relative "xsdvi/tree/element"
7
+ require_relative "xsdvi/tree/builder"
8
+ require_relative "xsdvi/svg/generator"
9
+ require_relative "xsdvi/svg/symbol"
10
+ require_relative "xsdvi/svg/symbols/all"
11
+ require_relative "xsdvi/svg/symbols/any"
12
+ require_relative "xsdvi/svg/symbols/any_attribute"
13
+ require_relative "xsdvi/svg/symbols/attribute"
14
+ require_relative "xsdvi/svg/symbols/choice"
15
+ require_relative "xsdvi/svg/symbols/element"
16
+ require_relative "xsdvi/svg/symbols/field"
17
+ require_relative "xsdvi/svg/symbols/key"
18
+ require_relative "xsdvi/svg/symbols/keyref"
19
+ require_relative "xsdvi/svg/symbols/loop"
20
+ require_relative "xsdvi/svg/symbols/schema"
21
+ require_relative "xsdvi/svg/symbols/selector"
22
+ require_relative "xsdvi/svg/symbols/sequence"
23
+ require_relative "xsdvi/svg/symbols/unique"
24
+ require_relative "xsdvi/utils/writer"
25
+ require_relative "xsdvi/utils/resource_loader"
26
+ require_relative "xsdvi/utils/width_calculator"
27
+
28
+ module Xsdvi
29
+ class Error < StandardError; end
30
+ end
@@ -0,0 +1,9 @@
1
+ <symbol class='button' id='plus'>
2
+ <rect x='1' y='1' width='10' height='10'/>
3
+ <line x1='3' y1='6' x2='9' y2='6'/>
4
+ <line x1='6' y1='3' x2='6' y2='9'/>
5
+ </symbol>
6
+ <symbol class='button' id='minus'>
7
+ <rect x='1' y='1' width='10' height='10'/>
8
+ <line x1='3' y1='6' x2='9' y2='6'/>
9
+ </symbol>
@@ -0,0 +1 @@
1
+ <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
@@ -0,0 +1,7 @@
1
+ <rect class='button' x='300' y='10' width='20' height='20' onclick='collapseAll()'/>
2
+ <line x1='303' y1='20' x2='317' y2='20'/>
3
+ <text x='330' y='20'>collapse all</text>
4
+ <rect class='button' x='400' y='10' width='20' height='20' onclick='expandAll()'/>
5
+ <line x1='403' y1='20' x2='417' y2='20'/>
6
+ <line x1='410' y1='13' x2='410' y2='27'/>
7
+ <text x='430' y='20'>expand all</text>
@@ -0,0 +1,265 @@
1
+ <script type='text/ecmascript'><![CDATA[
2
+
3
+ var efBoxes = [];
4
+ var eSvg = null;
5
+
6
+ ////////// loadSVG()
7
+ function loadSVG() {
8
+ efBoxes = getElementsByClassName('box', document.getElementsByTagName('g'));
9
+ eSvg = document.getElementById('svg');
10
+ expandAll();
11
+ }
12
+
13
+ ////////// getElementsByClassName(string, nodeList)
14
+ function getElementsByClassName(sClass, nlNodes) {
15
+ var elements = [];
16
+ for (var i=0; i<nlNodes.length; i++) {
17
+ if(nlNodes.item(i).nodeType==1 && sClass==nlNodes.item(i).getAttribute('class')) {
18
+ elements.push(nlNodes.item(i));
19
+ }
20
+ }
21
+ return elements;
22
+ }
23
+
24
+ ////////// show(string)
25
+ function show(sId) {
26
+ var useElement = document.getElementById('s'+sId);
27
+ var moveNext = false;
28
+ var eBoxLast;
29
+ var maxX = 500;
30
+
31
+ if (notPlus(useElement)) {
32
+ eBoxLast = document.getElementById(sId);
33
+ setPlus(useElement);
34
+ for (var i=0; i<efBoxes.length; i++) {
35
+ var eBox = efBoxes[i];
36
+ if (moveNext) {
37
+ move(eBoxLast, eBox);
38
+ }
39
+ else if (isDescendant(sId, eBox.id)) {
40
+ eBox.setAttribute('visibility', 'hidden');
41
+ }
42
+ else if (isHigherBranch(sId, eBox.id)) {
43
+ move(eBoxLast, eBox);
44
+ moveNext = true;
45
+ }
46
+ if (eBox.getAttribute('visibility') != 'hidden') {
47
+ eBoxLast = eBox;
48
+ x = xTrans(eBox);
49
+ if (x > maxX) maxX = x;
50
+ }
51
+ }
52
+ }
53
+
54
+ else {
55
+ setMinus(useElement);
56
+ var skipDescendantsOf;
57
+ for (var i=0; i<efBoxes.length; i++) {
58
+ var eBox = efBoxes[i];
59
+ if (moveNext) {
60
+ move(eBoxLast, eBox);
61
+ }
62
+ else if (isDescendant(sId, eBox.id) && (!skipDescendantsOf || !isDescendant(skipDescendantsOf.id, eBox.id))) {
63
+ eBox.setAttribute('visibility', 'visible');
64
+ move(eBoxLast, eBox);
65
+ if (nextClosed(eBox)) skipDescendantsOf = eBox;
66
+ }
67
+ else if (isHigherBranch(sId, eBox.id)) {
68
+ move(eBoxLast, eBox);
69
+ moveNext = true;
70
+ }
71
+ if (eBox.getAttribute('visibility') != 'hidden') {
72
+ eBoxLast = eBox;
73
+ x = xTrans(eBox);
74
+ if (x > maxX) maxX = x;
75
+ }
76
+ }
77
+ }
78
+ //setHeight(yTrans(eBoxLast)+"+(AbstractSymbol.MAX_HEIGHT+AbstractSymbol.Y_INDENT)+");\n"+
79
+ setHeight(yTrans(eBoxLast)+%HEIGHT_SUM%);
80
+ setWidth(maxX+360);
81
+ }
82
+
83
+ ////////// collapseAll()
84
+ function collapseAll() {
85
+ for (var i=0; i<efBoxes.length; i++) {
86
+ var eBox = efBoxes[i];
87
+ var useElement = document.getElementById('s'+eBox.id);
88
+ if (useElement) setPlus(useElement);
89
+ if (eBox.id != '_1') eBox.setAttribute('visibility', 'hidden');
90
+ }
91
+ setHeight(400);
92
+ setWidth(500);
93
+ }
94
+
95
+ ////////// expandAll()
96
+ function expandAll() {
97
+ var eBoxLast;
98
+ var maxX = 0;
99
+ for (var i=0; i<efBoxes.length; i++) {
100
+ var eBox = efBoxes[i];
101
+ var useElement = document.getElementById('s'+eBox.id);
102
+ if (useElement) setMinus(useElement);
103
+ move(eBoxLast, eBox);
104
+ eBox.setAttribute('visibility', 'visible');
105
+ eBoxLast = eBox;
106
+ var x = xTrans(eBox);
107
+ if (x > maxX) maxX = x;
108
+ }
109
+ //setHeight(yTrans(eBoxLast)+"+(AbstractSymbol.MAX_HEIGHT+AbstractSymbol.Y_INDENT)+");\n"+
110
+ setHeight(yTrans(eBoxLast)+%HEIGHT_SUM%);
111
+ setWidth(maxX+360);
112
+ }
113
+
114
+ ////////// makeVisible(string)
115
+ function makeVisible(sId) {
116
+ var childNodes = document.getElementById(sId).childNodes;
117
+ var hidden = getElementsByClassName('hidden', childNodes);
118
+ var visible = getElementsByClassName('visible', childNodes);
119
+ inheritVisibility(hidden);
120
+ hiddenVisibility(visible);
121
+ }
122
+
123
+ ////////// makeHidden(string)
124
+ function makeHidden(sId) {
125
+ var childNodes = document.getElementById(sId).childNodes;
126
+ var hidden = getElementsByClassName('hidden', childNodes);
127
+ var visible = getElementsByClassName('visible', childNodes);
128
+ inheritVisibility(visible);
129
+ hiddenVisibility(hidden);
130
+ }
131
+
132
+ ////////// inheritVisibility(element[])
133
+ function inheritVisibility(efElements) {
134
+ for (var i=0; i<efElements.length; i++) {
135
+ efElements[i].setAttribute('visibility', 'inherit');
136
+ }
137
+ }
138
+
139
+ ////////// hiddenVisibility(element[])
140
+ function hiddenVisibility(efElements) {
141
+ for (var i=0; i<efElements.length; i++) {
142
+ efElements[i].setAttribute('visibility', 'hidden');
143
+ }
144
+ }
145
+
146
+ ////////// nextClosed(element)
147
+ function nextClosed(eBox) {
148
+ var useElement = document.getElementById('s'+eBox.id);
149
+ return (useElement && !notPlus(useElement));
150
+ }
151
+
152
+ ////////// isHigherBranch(string, string)
153
+ function isHigherBranch(sSerialLower, sSerialHigher) {
154
+ var sLower = sSerialLower.split('_');
155
+ var sHigher = sSerialHigher.split('_');
156
+ for (var i=0; i<sLower.length; i++) {
157
+ if (Number(sHigher[i]) > Number(sLower[i])) return true;
158
+ else if (Number(sHigher[i]) < Number(sLower[i])) return false;
159
+ }
160
+ return false;
161
+ }
162
+
163
+ ////////// isOnHigherLevel(element, element)
164
+ function isOnHigherLevel(eBoxLower, eBoxHigher) {
165
+ var sLower = eBoxLower.id.split('_');
166
+ var sHigher = eBoxHigher.id.split('_');
167
+ for (var i=0; i<sLower.length; i++) {
168
+ if (Number(sHigher[i]) > Number(sLower[i])) return true;
169
+ }
170
+ return false;
171
+ }
172
+
173
+ ////////// isDescendant(string, string)
174
+ function isDescendant(sSerialAsc, sSerialDesc) {
175
+ return (sSerialDesc.length > sSerialAsc.length && sSerialDesc.indexOf(sSerialAsc) === 0);
176
+ }
177
+
178
+ ////////// getParent(element)
179
+ function getParent(eBox) {
180
+ var serial = eBox.id.substring(0, eBox.id.lastIndexOf('_'));
181
+ return document.getElementById(serial);
182
+ }
183
+
184
+ ////////// move(element, element)
185
+ function move(eBoxLast, eBox) {
186
+ if (!eBoxLast) return;
187
+ if (isOnHigherLevel(eBoxLast, eBox)) {
188
+ //setYTrans(eBox, yTrans(eBoxLast)+"+(AbstractSymbol.MAX_HEIGHT+AbstractSymbol.Y_INDENT)+");\n"+
189
+ var attDescHeight = eBoxLast.getAttribute('data-desc-height-rest');
190
+ var attDescX = Number(eBoxLast.getAttribute('data-desc-x'));
191
+ var attX = xTrans(eBox);
192
+ var descHeight = Number(attDescHeight);
193
+ var heightAddon = 0;
194
+
195
+ var currWidth = eBox.getElementsByClassName("shadow")[0];
196
+ if (currWidth) {
197
+ currWidth = Number(currWidth.getAttribute("width"));
198
+ } else {
199
+ currWidth = 0;
200
+ }
201
+ if(descHeight && ((attDescX >= attX && attDescX < attX + currWidth) || (attX < attDescX))) heightAddon = descHeight;
202
+
203
+ setYTrans(eBox, yTrans(eBoxLast)+%HEIGHT_SUM%+heightAddon);
204
+ var parent = getParent(eBox);
205
+ var line = document.getElementById('p'+eBox.id);
206
+ if (!parent || !line) return;
207
+ //" line.y1.baseVal.valueInSpecifiedUnits = yTrans(parent)-yTrans(eBox)+"+AbstractSymbol.MAX_HEIGHT/2+";
208
+ //line.setAttribute('y1', String(yTrans(parent)-yTrans(eBox)+"+AbstractSymbol.MAX_HEIGHT/2+"));\n"+
209
+ line.setAttribute('y1', String(yTrans(parent)-yTrans(eBox)+%HEIGHT_HALF%));
210
+ }
211
+ else {
212
+ setYTrans(eBox, yTrans(eBoxLast));
213
+ }
214
+ }
215
+
216
+ ////////// notPlus(element)
217
+ function notPlus(eUseElement) {
218
+ return (eUseElement.getAttributeNS('http://www.w3.org/1999/xlink', 'href') != '#plus');
219
+ }
220
+
221
+ ////////// setPlus(element)
222
+ function setPlus(eUseElement) {
223
+ eUseElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#plus');
224
+ }
225
+
226
+ ////////// setMinus(element)
227
+ function setMinus(eUseElement) {
228
+ eUseElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#minus');
229
+ }
230
+
231
+ ////////// setHeight(number)
232
+ function setHeight(nHeight) {
233
+ eSvg.setAttribute('height', nHeight);
234
+ }
235
+
236
+ ////////// setWidth(number)
237
+ function setWidth(nWidth) {
238
+ eSvg.setAttribute('width', nWidth);
239
+ }
240
+
241
+ ////////// xyTrans(element)
242
+ function xTrans(eBox) {
243
+ //" return eBox.transform.baseVal.getItem(0).matrix.e;
244
+ var transform = eBox.getAttribute('transform');
245
+ var x = Number(transform.substring(10, Number(transform.length)-1).split(',')[0]);
246
+ if(!x) x = 0;
247
+ return x;
248
+ }
249
+
250
+ ////////// yTrans(element)
251
+ function yTrans(eBox) {
252
+ //" return eBox.transform.baseVal.getItem(0).matrix.f;
253
+ var transform = eBox.getAttribute('transform');
254
+ var y = Number(transform.substring(10, Number(transform.length)-1).split(',')[1]);
255
+ if(!y) y = 0;
256
+ return y;
257
+ }
258
+
259
+ ////////// setYTrans(element, number)
260
+ function setYTrans(eBox, nValue) {
261
+ //" return eBox.transform.baseVal.getItem(0).matrix.f = nValue;
262
+ eBox.setAttribute('transform', 'translate('+xTrans(eBox)+','+nValue+')');
263
+ }
264
+
265
+ ]]></script>
@@ -0,0 +1,29 @@
1
+ svg {pointer-events: none;}
2
+ text {font-family: arial; font-size: 11px;}
3
+ line, polyline, polygon {fill: none; stroke: black;}
4
+
5
+ .strong {font-size: 12px; font-weight: bold;}
6
+ .small {font-size: 10px;}
7
+ .big {font-size: 15px; fill: #882222;}
8
+
9
+ .button {fill: white; stroke: black; pointer-events: all;}
10
+ .shadow {fill: #ccccd8; stroke: none;}
11
+ .connection {fill: none; stroke: #666666;}
12
+ .empty {fill: none; stroke: black;}
13
+ .filled {fill: black; stroke: none;}
14
+
15
+ .boxelement, .boxany, .boxattribute1, .boxanyattribute {fill: #FFFFBB; stroke: #776633; pointer-events: all;}
16
+ .boxelementoptional {fill: #FFFFBB; stroke: #776633; pointer-events: all; stroke-dasharray: 2;}
17
+ .boxattribute2 {fill: #FFFFBB; stroke: #776633; pointer-events: all; stroke-dasharray: 2;}
18
+ .boxschema, .boxloop, .boxcompositor {fill: #E7EBF3; stroke: #666677;}
19
+ .boxselector, .boxfield, .boxidc {fill: #E0F7B7; stroke: #667733;}
20
+
21
+ .lax {fill: white; stroke: black;}
22
+ .skip {fill: #cc6666; stroke: black;}
23
+ .strict {fill: black; stroke: none;}
24
+
25
+ .border {fill: #f9f9f9; stroke: #dddddd;}
26
+
27
+ .elementlink {fill: blue;}
28
+
29
+ .desc {fill: #888888;}
@@ -0,0 +1,3 @@
1
+ <style type='text/css'><![CDATA[
2
+ %STYLE%
3
+ ]]></style>
@@ -0,0 +1 @@
1
+ <?xml-stylesheet href='%STYLE_URI%' type='text/css'?>
@@ -0,0 +1 @@
1
+ </svg>
@@ -0,0 +1 @@
1
+ <svg id='svg' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' onload='loadSVG();'>
@@ -0,0 +1 @@
1
+ <title>XsdVi</title>
@@ -0,0 +1 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>