wax 0.9.5 → 0.9.7
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/address.rb +19 -5
- data/lib/car.rb +16 -3
- data/lib/cd_demo.rb +6 -6
- data/lib/person.rb +18 -4
- data/lib/tutorial.rb +3 -3
- data/lib/wax.rb +127 -46
- data/lib/xml_util.rb +135 -8
- data/test/test_wax.rb +245 -56
- data/test/test_xmlutil.rb +11 -13
- metadata +2 -2
data/lib/address.rb
CHANGED
@@ -6,11 +6,25 @@ class Address
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def to_xml(wax)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
# Chaining approach
|
10
|
+
#wax.start('address').
|
11
|
+
# child('street', @street).
|
12
|
+
# child('city', @city).
|
13
|
+
# child('state', @state).
|
14
|
+
# child('zip', @zip).
|
15
|
+
# end!
|
16
|
+
|
17
|
+
# Non-chaining approach
|
18
|
+
# Put the current object in a local variable
|
19
|
+
# so it can be accessed in the block passed to the write method.
|
20
|
+
address = self
|
21
|
+
wax.write do
|
22
|
+
start 'address'
|
23
|
+
child 'street', address.street
|
24
|
+
child 'city', address.city
|
25
|
+
child 'state', address.state
|
26
|
+
child 'zip', address.zip
|
14
27
|
end!
|
28
|
+
end
|
15
29
|
end
|
16
30
|
end
|
data/lib/car.rb
CHANGED
@@ -6,10 +6,23 @@ class Car
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def to_xml(wax)
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
# Chaining approach
|
10
|
+
#wax.start('car').attr('year', @year).
|
11
|
+
# child('make', @make).
|
12
|
+
# child('model', @model).
|
13
|
+
# end!
|
14
|
+
|
15
|
+
# Non-chaining approach
|
16
|
+
# Put the current object in a local variable
|
17
|
+
# so it can be accessed in the block passed to the write method.
|
18
|
+
car = self
|
19
|
+
wax.write do
|
20
|
+
start 'car'
|
21
|
+
attr 'year', car.year
|
22
|
+
child 'make', car.make
|
23
|
+
child 'model', car.model
|
12
24
|
end!
|
25
|
+
end
|
13
26
|
end
|
14
27
|
end
|
15
28
|
|
data/lib/cd_demo.rb
CHANGED
@@ -2,15 +2,15 @@ require 'wax'
|
|
2
2
|
|
3
3
|
url = "http://www.ociweb.com"
|
4
4
|
WAX.write($stdout, "1.0") do
|
5
|
+
xslt "artist.xslt"
|
6
|
+
dtd "#{url}/xml/music.dtd"
|
7
|
+
start "artist"
|
8
|
+
attr "name", "Gardot, Melody"
|
9
|
+
namespace nil, "#{url}/music", "#{url}/xml/music.xsd"
|
10
|
+
namespace "date", "#{url}/date", "#{url}/xml/date.xsd"
|
5
11
|
comment "This is one of my favorite CDs!"
|
6
|
-
dtd "#{url}/xml/cd.dtd"
|
7
|
-
xslt "cd.xslt"
|
8
12
|
start "cd"
|
9
13
|
attr "year", 2008
|
10
|
-
namespace nil, "#{url}/music", "#{url}/xml/cd.xsd"
|
11
|
-
namespace "date", "#{url}/date", "#{url}/xml/date.xsd"
|
12
|
-
start "artist"
|
13
|
-
attr "name", "Gardot, Melody"
|
14
14
|
child "title", "Worrisome Heart"
|
15
15
|
child "date", "purchaseDate", "4/3/2008"
|
16
16
|
end
|
data/lib/person.rb
CHANGED
@@ -6,13 +6,27 @@ class Person
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def to_xml(wax)
|
9
|
-
|
10
|
-
@
|
11
|
-
wax
|
9
|
+
# Chaining approach
|
10
|
+
#wax.start('person').attr('birthdate', @birthdate).child('name', @name)
|
11
|
+
#@address.to_xml(wax)
|
12
|
+
#wax.end!
|
13
|
+
|
14
|
+
# Non-chaining approach
|
15
|
+
# Put the current object in a local variable
|
16
|
+
# so it can be accessed in the block passed to the write method.
|
17
|
+
person = self
|
18
|
+
wax.write do
|
19
|
+
start 'person'
|
20
|
+
attr 'birthdate', person.birthdate
|
21
|
+
child 'name', person.name
|
22
|
+
person.address.to_xml(self) # self is the WAX object here
|
23
|
+
end!
|
24
|
+
end
|
12
25
|
end
|
13
26
|
end
|
14
27
|
|
15
|
-
if $PROGRAM_NAME == __FILE__
|
28
|
+
if $PROGRAM_NAME == __FILE__
|
29
|
+
# || $PROGRAM_NAME =~ /\/rake/
|
16
30
|
require 'address'
|
17
31
|
require 'wax'
|
18
32
|
|
data/lib/tutorial.rb
CHANGED
@@ -53,7 +53,7 @@ end
|
|
53
53
|
|
54
54
|
out 'Without indentation, on a single line:'
|
55
55
|
WAX.write do
|
56
|
-
|
56
|
+
no_indents_or_crs
|
57
57
|
start 'car'
|
58
58
|
child 'model', 'Prius'
|
59
59
|
end
|
@@ -155,7 +155,7 @@ out 'Associate an XML Schema:'
|
|
155
155
|
WAX.write do
|
156
156
|
start 'car'
|
157
157
|
attr 'year', 2008
|
158
|
-
namespace
|
158
|
+
namespace '', 'http://www.ociweb.com/cars', 'car.xsd'
|
159
159
|
child 'model', 'Prius'
|
160
160
|
end
|
161
161
|
# <car year='2008'
|
@@ -169,7 +169,7 @@ out 'Associate multiple XML Schemas:'
|
|
169
169
|
WAX.write do
|
170
170
|
start 'car'
|
171
171
|
attr 'year', 2008
|
172
|
-
namespace
|
172
|
+
namespace '', 'http://www.ociweb.com/cars', 'car.xsd'
|
173
173
|
namespace 'm', 'http://www.ociweb.com/model', 'model.xsd'
|
174
174
|
child 'm', 'model', 'Prius'
|
175
175
|
end
|
data/lib/wax.rb
CHANGED
@@ -32,6 +32,11 @@ class WAX
|
|
32
32
|
# If they are, a RuntimeError is raised.
|
33
33
|
STATES = [:in_prolog, :in_start_tag, :in_element, :after_root]
|
34
34
|
|
35
|
+
NONWINDOWS_CR = "\n"
|
36
|
+
WINDOWS_CR = "\r\n"
|
37
|
+
|
38
|
+
attr_reader :state
|
39
|
+
|
35
40
|
# Creates a WAX object, invokes the specified block on it
|
36
41
|
# and calls close on the WAX object.
|
37
42
|
# The writer can be a String file path, an IO object such as a File,
|
@@ -42,6 +47,11 @@ class WAX
|
|
42
47
|
wax = WAX.new(writer, version)
|
43
48
|
wax.instance_exec(&proc)
|
44
49
|
wax.close
|
50
|
+
wax # return instance so caller can get configuration info. like @cr
|
51
|
+
end
|
52
|
+
|
53
|
+
def write(writer=$stdout, version=nil, &proc)
|
54
|
+
instance_eval(&proc)
|
45
55
|
end
|
46
56
|
|
47
57
|
# Initializes new instances of this class.
|
@@ -49,6 +59,8 @@ class WAX
|
|
49
59
|
@attr_on_new_line = false
|
50
60
|
@check_me = true
|
51
61
|
@close_stream = writer != $stdout
|
62
|
+
@dtd_specified = false
|
63
|
+
@in_commented_start = false
|
52
64
|
@dtd_file_path = nil
|
53
65
|
@entity_defs = []
|
54
66
|
@has_content = @has_indented_content = false
|
@@ -59,6 +71,8 @@ class WAX
|
|
59
71
|
@prefixes_stack = []
|
60
72
|
@state = :in_prolog
|
61
73
|
@writer = writer
|
74
|
+
@xslt_specified = false
|
75
|
+
use_non_windows_cr
|
62
76
|
write_xml_declaration(version)
|
63
77
|
end
|
64
78
|
|
@@ -69,9 +83,9 @@ class WAX
|
|
69
83
|
# to indicate whether the attribute should be written on a new line.
|
70
84
|
def attr(p1, p2, p3=nil, p4=nil)
|
71
85
|
if (p3 == nil)
|
72
|
-
prefix, name, value, new_line = nil, p1, p2,
|
86
|
+
prefix, name, value, new_line = nil, p1, p2, @attr_on_new_line
|
73
87
|
elsif (p4 == nil)
|
74
|
-
prefix, name, value, new_line = p1, p2, p3,
|
88
|
+
prefix, name, value, new_line = p1, p2, p3, @attr_on_new_line
|
75
89
|
else
|
76
90
|
prefix, name, value, new_line = p1, p2, p3, p4
|
77
91
|
end
|
@@ -80,11 +94,11 @@ class WAX
|
|
80
94
|
bad_state("attr") unless @state == :in_start_tag
|
81
95
|
|
82
96
|
unless prefix == nil
|
83
|
-
XMLUtil.
|
97
|
+
XMLUtil.verify_name(prefix)
|
84
98
|
@pending_prefixes << prefix
|
85
99
|
end
|
86
100
|
|
87
|
-
XMLUtil.
|
101
|
+
XMLUtil.verify_name(name)
|
88
102
|
value = XMLUtil.escape(value)
|
89
103
|
end
|
90
104
|
|
@@ -168,19 +182,40 @@ class WAX
|
|
168
182
|
write_indent if @parent_stack.size > 0
|
169
183
|
|
170
184
|
out "<!-- #{text} -->"
|
171
|
-
out "
|
185
|
+
out "#{@cr}" if will_indent and @parent_stack.size == 0
|
186
|
+
|
187
|
+
self
|
188
|
+
end
|
189
|
+
|
190
|
+
# Writes a commented start tag for a given element name,
|
191
|
+
# but doesn't terminate it.
|
192
|
+
def commented_start(p1, p2=nil)
|
193
|
+
if (p2 == nil)
|
194
|
+
# only specified element name
|
195
|
+
prefix, name = nil, p1
|
196
|
+
else
|
197
|
+
# specified element namespace prefix, name and text
|
198
|
+
prefix, name = p1, p2
|
199
|
+
end
|
200
|
+
|
201
|
+
@in_commented_start = true
|
202
|
+
start(prefix, name)
|
203
|
+
@in_commented_start = false
|
172
204
|
|
173
205
|
self
|
174
206
|
end
|
175
207
|
|
176
208
|
# Writes a DOCTYPE that associates a DTD with the XML document.
|
177
209
|
def dtd(file_path)
|
210
|
+
raise "can't specify more than one DTD" if @dtd_specified
|
211
|
+
|
178
212
|
if @check_me
|
179
213
|
bad_state("dtd") unless @state == :in_prolog
|
180
214
|
XMLUtil.verify_uri(file_path)
|
181
215
|
end
|
182
216
|
|
183
217
|
@dtd_file_path = file_path
|
218
|
+
@dtd_specified = true
|
184
219
|
self
|
185
220
|
end
|
186
221
|
|
@@ -202,11 +237,17 @@ class WAX
|
|
202
237
|
# are no longer in scope.
|
203
238
|
@prefixes_stack.pop
|
204
239
|
|
240
|
+
# Check for hypen at beginning of element name
|
241
|
+
# which indicates that the commentedStart method was used.
|
242
|
+
was_commented_start = name[0] == '-'[0]
|
243
|
+
|
205
244
|
if @has_content
|
206
245
|
write_indent if @has_indented_content
|
207
|
-
out
|
246
|
+
out '</'
|
247
|
+
out was_commented_start ? name[1..-1] : name
|
248
|
+
out was_commented_start ? '-->' : '>'
|
208
249
|
else
|
209
|
-
out
|
250
|
+
out was_commented_start ? '/-->' : '/>'
|
210
251
|
end
|
211
252
|
|
212
253
|
@has_content = @has_indented_content = true # new setting for parent
|
@@ -228,6 +269,11 @@ class WAX
|
|
228
269
|
entity_def(name + " SYSTEM", file_path)
|
229
270
|
end
|
230
271
|
|
272
|
+
# Gets the carriage return characters currently being used.
|
273
|
+
def get_cr
|
274
|
+
@cr
|
275
|
+
end
|
276
|
+
|
231
277
|
# Gets the indentation characters being used.
|
232
278
|
def get_indent
|
233
279
|
@indent
|
@@ -277,7 +323,7 @@ class WAX
|
|
277
323
|
if @check_me
|
278
324
|
bad_state("namespace") unless @state == :in_start_tag
|
279
325
|
|
280
|
-
XMLUtil.
|
326
|
+
XMLUtil.verify_name(prefix) if has_prefix
|
281
327
|
XMLUtil.verify_uri(uri)
|
282
328
|
XMLUtil.verify_uri(schema_path) unless schema_path == nil
|
283
329
|
end
|
@@ -321,11 +367,26 @@ class WAX
|
|
321
367
|
text text, true, @check_me
|
322
368
|
end
|
323
369
|
|
370
|
+
# Don't output indent output or write carriage returns.
|
371
|
+
# Write out the XML on a single line.
|
372
|
+
def no_indents_or_crs
|
373
|
+
set_indent nil
|
374
|
+
end
|
375
|
+
|
376
|
+
# Writes the to_s value of an Object to the writer.
|
377
|
+
def out(data)
|
378
|
+
raise "attempting to out XML after close has been called" unless @writer
|
379
|
+
@writer.write(data.to_s)
|
380
|
+
end
|
381
|
+
|
324
382
|
# Writes a processing instruction.
|
325
383
|
def processing_instruction(target, data)
|
326
384
|
if @check_me
|
327
385
|
bad_state("pi") if @state == :after_root
|
328
|
-
|
386
|
+
|
387
|
+
# Special handling for this processing instruction
|
388
|
+
# since starting with "xml" is reserved.
|
389
|
+
XMLUtil.verify_name(target) unless target == "xml-stylesheet"
|
329
390
|
end
|
330
391
|
|
331
392
|
@has_content = @has_indented_content = true
|
@@ -333,17 +394,17 @@ class WAX
|
|
333
394
|
write_indent if @parent_stack.size > 0
|
334
395
|
|
335
396
|
out "<?#{target} #{data}?>"
|
336
|
-
out("
|
397
|
+
out("#{@cr}") if will_indent and @parent_stack.size == 0
|
337
398
|
|
338
399
|
self
|
339
400
|
end
|
340
401
|
|
341
402
|
# Sets the indentation characters to use.
|
342
403
|
# The only valid values are
|
343
|
-
# a single tab, one or more spaces, an empty string, or
|
404
|
+
# a single tab, one or more spaces, an empty string, or nil.
|
344
405
|
# Passing "" causes elements to be output on separate lines,
|
345
406
|
# but not indented.
|
346
|
-
# Passing
|
407
|
+
# Passing nil causes all output to be on a single line.
|
347
408
|
def set_indent(indent)
|
348
409
|
if indent == nil
|
349
410
|
@indent = indent
|
@@ -355,7 +416,7 @@ class WAX
|
|
355
416
|
raise ArgumentError, "can't indent a negative number of spaces"
|
356
417
|
end
|
357
418
|
|
358
|
-
if count > 4
|
419
|
+
if @check_me && count > 4
|
359
420
|
raise ArgumentError, "#{count} is an unreasonable indentation"
|
360
421
|
end
|
361
422
|
|
@@ -364,23 +425,27 @@ class WAX
|
|
364
425
|
return
|
365
426
|
|
366
427
|
elsif indent.kind_of?(String)
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
428
|
+
if @check_me
|
429
|
+
# Note that the parens on the next line are necessary
|
430
|
+
# because the assignment operator has higher precedence than "or".
|
431
|
+
valid = (indent == nil or indent.length == 0 or indent == "\t")
|
432
|
+
|
433
|
+
unless valid
|
434
|
+
# It can only be valid now if every character is a space.
|
435
|
+
valid = true
|
436
|
+
for i in 0...indent.length
|
437
|
+
unless indent[i] == 32 # space
|
438
|
+
valid = false
|
439
|
+
break
|
440
|
+
end
|
378
441
|
end
|
379
442
|
end
|
443
|
+
|
444
|
+
if !valid or (indent != nil and indent.length > 4)
|
445
|
+
raise ArgumentError, "invalid indent value #{indent}"
|
446
|
+
end
|
380
447
|
end
|
381
448
|
|
382
|
-
raise ArgumentError, "invalid indent value #{indent}" unless valid
|
383
|
-
|
384
449
|
@indent = indent
|
385
450
|
|
386
451
|
else
|
@@ -420,10 +485,10 @@ class WAX
|
|
420
485
|
if @check_me
|
421
486
|
bad_state("start") if @state == :after_root
|
422
487
|
if prefix != nil
|
423
|
-
XMLUtil.
|
488
|
+
XMLUtil.verify_name(prefix)
|
424
489
|
@pending_prefixes << prefix
|
425
490
|
end
|
426
|
-
XMLUtil.
|
491
|
+
XMLUtil.verify_name(name)
|
427
492
|
end
|
428
493
|
|
429
494
|
# If this is the root element ...
|
@@ -438,9 +503,15 @@ class WAX
|
|
438
503
|
has_prefix = prefix != nil and prefix.length > 0
|
439
504
|
qname = has_prefix ? prefix + ':' + name : name
|
440
505
|
|
441
|
-
|
442
|
-
|
443
|
-
|
506
|
+
if (@in_commented_start)
|
507
|
+
out '<!--' + qname
|
508
|
+
# Add a "marker" to the element name on the stack
|
509
|
+
# so the end method knows to terminate the comment.
|
510
|
+
@parent_stack.push('-' + qname)
|
511
|
+
else
|
512
|
+
out '<' + qname
|
513
|
+
@parent_stack.push(qname)
|
514
|
+
end
|
444
515
|
|
445
516
|
# No namespace prefixes have been associated with this element yet.
|
446
517
|
@prefixes_stack.push(nil)
|
@@ -478,12 +549,26 @@ class WAX
|
|
478
549
|
text = XMLUtil.escape(text) if escape
|
479
550
|
out text
|
480
551
|
elsif newline
|
481
|
-
out "
|
552
|
+
out "#{@cr}"
|
482
553
|
end
|
483
554
|
|
484
555
|
self
|
485
556
|
end
|
486
557
|
|
558
|
+
# Uses #{@cr} for carriage returns which is appropriate
|
559
|
+
# on every platform except Windows.
|
560
|
+
# Note that this is the default.
|
561
|
+
def use_non_windows_cr
|
562
|
+
@cr = NONWINDOWS_CR
|
563
|
+
end
|
564
|
+
|
565
|
+
# Uses \r#{@cr} for carriage returns which is appropriate
|
566
|
+
# only on the Windows platform.
|
567
|
+
# Note that this is not the default.
|
568
|
+
def use_windows_cr
|
569
|
+
@cr = WINDOWS_CR
|
570
|
+
end
|
571
|
+
|
487
572
|
# Verifies that all the pending namespace prefix are currently in scope.
|
488
573
|
# ArgumentError is raises if any aren't in scope.
|
489
574
|
def verify_prefixes
|
@@ -502,12 +587,6 @@ class WAX
|
|
502
587
|
@indent != nil
|
503
588
|
end
|
504
589
|
|
505
|
-
# Writes the to_s value of an Object to the writer.
|
506
|
-
def out(data)
|
507
|
-
raise "attempting to out XML after close has been called" unless @writer
|
508
|
-
@writer.write(data.to_s)
|
509
|
-
end
|
510
|
-
|
511
590
|
# Writes a DOCTYPE.
|
512
591
|
def write_doctype(root_element_name)
|
513
592
|
return if @dtd_file_path == nil and @entity_defs.empty?
|
@@ -519,25 +598,25 @@ class WAX
|
|
519
598
|
out " ["
|
520
599
|
|
521
600
|
@entity_defs.each do |entity_def|
|
522
|
-
out "
|
601
|
+
out "#{@cr}" + @indent if will_indent
|
523
602
|
out "<!ENTITY #{entity_def}>"
|
524
603
|
end
|
525
604
|
|
526
|
-
out "
|
605
|
+
out "#{@cr}" if will_indent
|
527
606
|
out ']'
|
528
607
|
|
529
608
|
@entity_defs.clear
|
530
609
|
end
|
531
610
|
|
532
611
|
out '>'
|
533
|
-
out "
|
612
|
+
out "#{@cr}" if will_indent
|
534
613
|
end
|
535
614
|
|
536
615
|
# Writes the proper amount of indentation
|
537
616
|
# given the current nesting of elements.
|
538
617
|
def write_indent
|
539
618
|
return unless will_indent
|
540
|
-
out "
|
619
|
+
out "#{@cr}"
|
541
620
|
for i in 0...@parent_stack.size
|
542
621
|
out @indent
|
543
622
|
end
|
@@ -554,7 +633,7 @@ class WAX
|
|
554
633
|
@namespace_uri_to_schema_path_map.each_pair do |uri, path|
|
555
634
|
if schema_location.length > 0 # not first pair output
|
556
635
|
if will_indent
|
557
|
-
schema_location << "
|
636
|
+
schema_location << "#{@cr}"
|
558
637
|
for i in 0..@parent_stack.size
|
559
638
|
schema_location << @indent
|
560
639
|
end
|
@@ -580,20 +659,22 @@ class WAX
|
|
580
659
|
XMLUtil.verify_version(version) if @check_me
|
581
660
|
|
582
661
|
out "<?xml version=\"#{version}\" " +
|
583
|
-
"encoding=\"#{XMLUtil::DEFAULT_ENCODING}\"
|
662
|
+
"encoding=\"#{XMLUtil::DEFAULT_ENCODING}\"?>#{@cr}"
|
584
663
|
end
|
585
664
|
|
586
665
|
# Writes an "xml-stylesheet" processing instruction.
|
587
666
|
def xslt(file_path)
|
667
|
+
raise "can't specify more than one XSLT" if @xslt_specified
|
668
|
+
|
588
669
|
if @check_me
|
589
670
|
bad_state("xslt") unless @state == :in_prolog
|
590
671
|
XMLUtil.verify_uri(file_path)
|
591
672
|
end
|
592
673
|
|
593
|
-
@state = :in_prolog
|
594
|
-
|
595
674
|
processing_instruction("xml-stylesheet",
|
596
675
|
"type=\"text/xsl\" href=\"#{file_path}\"")
|
676
|
+
|
677
|
+
@xslt_specified = true
|
597
678
|
end
|
598
679
|
|
599
680
|
private :bad_state, :is_in_scope_prefix, :terminate_start,
|
data/lib/xml_util.rb
CHANGED
@@ -23,7 +23,113 @@ module XMLUtil
|
|
23
23
|
# The default encoding used in XML declarations.
|
24
24
|
DEFAULT_ENCODING = "UTF-8"
|
25
25
|
|
26
|
-
|
26
|
+
# The following regular expressions
|
27
|
+
# were taken from the W3C XML Recommenation:
|
28
|
+
BASE_CHAR_PATTERN =
|
29
|
+
"[\u0041-\u005A]|[\u0061-\u007A]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|" +
|
30
|
+
"[\u00F8-\u00FF]|[\u0100-\u0131]|[\u0134-\u013E]|[\u0141-\u0148]|" +
|
31
|
+
"[\u014A-\u017E]|[\u0180-\u01C3]|[\u01CD-\u01F0]|[\u01F4-\u01F5]|" +
|
32
|
+
"[\u01FA-\u0217]|[\u0250-\u02A8]|[\u02BB-\u02C1]|\u0386|" +
|
33
|
+
"[\u0388-\u038A]|\u038C|[\u038E-\u03A1]|[\u03A3-\u03CE]|" +
|
34
|
+
"[\u03D0-\u03D6]|\u03DA|\u03DC|\u03DE|\u03E0|[\u03E2-\u03F3]|" +
|
35
|
+
"[\u0401-\u040C]|[\u040E-\u044F]|[\u0451-\u045C]|[\u045E-\u0481]|" +
|
36
|
+
"[\u0490-\u04C4]|[\u04C7-\u04C8]|[\u04CB-\u04CC]|[\u04D0-\u04EB]|" +
|
37
|
+
"[\u04EE-\u04F5]|[\u04F8-\u04F9]|[\u0531-\u0556]|\u0559|" +
|
38
|
+
"[\u0561-\u0586]|[\u05D0-\u05EA]|[\u05F0-\u05F2]|[\u0621-\u063A]|" +
|
39
|
+
"[\u0641-\u064A]|[\u0671-\u06B7]|[\u06BA-\u06BE]|[\u06C0-\u06CE]|" +
|
40
|
+
"[\u06D0-\u06D3]|\u06D5|[\u06E5-\u06E6]|[\u0905-\u0939]|" +
|
41
|
+
"\u093D|[\u0958-\u0961]|[\u0985-\u098C]|[\u098F-\u0990]|" +
|
42
|
+
"[\u0993-\u09A8]|[\u09AA-\u09B0]|\u09B2|[\u09B6-\u09B9]|" +
|
43
|
+
"[\u09DC-\u09DD]|[\u09DF-\u09E1]|[\u09F0-\u09F1]|[\u0A05-\u0A0A]|" +
|
44
|
+
"[\u0A0F-\u0A10]|[\u0A13-\u0A28]|[\u0A2A-\u0A30]|[\u0A32-\u0A33]|" +
|
45
|
+
"[\u0A35-\u0A36]|[\u0A38-\u0A39]|[\u0A59-\u0A5C]|\u0A5E|" +
|
46
|
+
"[\u0A72-\u0A74]|[\u0A85-\u0A8B]|\u0A8D|[\u0A8F-\u0A91]|" +
|
47
|
+
"[\u0A93-\u0AA8]|[\u0AAA-\u0AB0]|[\u0AB2-\u0AB3]|[\u0AB5-\u0AB9]|" +
|
48
|
+
"\u0ABD|\u0AE0|[\u0B05-\u0B0C]|[\u0B0F-\u0B10]|[\u0B13-\u0B28]|" +
|
49
|
+
"[\u0B2A-\u0B30]|[\u0B32-\u0B33]|[\u0B36-\u0B39]|\u0B3D|" +
|
50
|
+
"[\u0B5C-\u0B5D]|[\u0B5F-\u0B61]|[\u0B85-\u0B8A]|[\u0B8E-\u0B90]|" +
|
51
|
+
"[\u0B92-\u0B95]|[\u0B99-\u0B9A]|\u0B9C|[\u0B9E-\u0B9F]|" +
|
52
|
+
"[\u0BA3-\u0BA4]|[\u0BA8-\u0BAA]|[\u0BAE-\u0BB5]|[\u0BB7-\u0BB9]|" +
|
53
|
+
"[\u0C05-\u0C0C]|[\u0C0E-\u0C10]|[\u0C12-\u0C28]|[\u0C2A-\u0C33]|" +
|
54
|
+
"[\u0C35-\u0C39]|[\u0C60-\u0C61]|[\u0C85-\u0C8C]|[\u0C8E-\u0C90]|" +
|
55
|
+
"[\u0C92-\u0CA8]|[\u0CAA-\u0CB3]|[\u0CB5-\u0CB9]|\u0CDE|" +
|
56
|
+
"[\u0CE0-\u0CE1]|[\u0D05-\u0D0C]|[\u0D0E-\u0D10]|[\u0D12-\u0D28]|" +
|
57
|
+
"[\u0D2A-\u0D39]|[\u0D60-\u0D61]|[\u0E01-\u0E2E]|\u0E30|" +
|
58
|
+
"[\u0E32-\u0E33]|[\u0E40-\u0E45]|[\u0E81-\u0E82]|\u0E84|" +
|
59
|
+
"[\u0E87-\u0E88]|\u0E8A|\u0E8D|[\u0E94-\u0E97]|[\u0E99-\u0E9F]|" +
|
60
|
+
"[\u0EA1-\u0EA3]|\u0EA5|\u0EA7|[\u0EAA-\u0EAB]|[\u0EAD-\u0EAE]|" +
|
61
|
+
"\u0EB0|[\u0EB2-\u0EB3]|\u0EBD|[\u0EC0-\u0EC4]|[\u0F40-\u0F47]|" +
|
62
|
+
"[\u0F49-\u0F69]|[\u10A0-\u10C5]|[\u10D0-\u10F6]|\u1100|" +
|
63
|
+
"[\u1102-\u1103]|[\u1105-\u1107]|\u1109|[\u110B-\u110C]|" +
|
64
|
+
"[\u110E-\u1112]|\u113C|\u113E|\u1140|\u114C|\u114E|\u1150|" +
|
65
|
+
"[\u1154-\u1155]|\u1159|[\u115F-\u1161]|\u1163|\u1165|\u1167|" +
|
66
|
+
"\u1169|[\u116D-\u116E]|[\u1172-\u1173]|\u1175|\u119E|\u11A8|" +
|
67
|
+
"\u11AB|[\u11AE-\u11AF]|[\u11B7-\u11B8]|\u11BA|[\u11BC-\u11C2]|" +
|
68
|
+
"\u11EB|\u11F0|\u11F9|[\u1E00-\u1E9B]|[\u1EA0-\u1EF9]|" +
|
69
|
+
"[\u1F00-\u1F15]|[\u1F18-\u1F1D]|[\u1F20-\u1F45]|[\u1F48-\u1F4D]|" +
|
70
|
+
"[\u1F50-\u1F57]|\u1F59|\u1F5B|\u1F5D|[\u1F5F-\u1F7D]|" +
|
71
|
+
"[\u1F80-\u1FB4]|[\u1FB6-\u1FBC]|\u1FBE|[\u1FC2-\u1FC4]|" +
|
72
|
+
"[\u1FC6-\u1FCC]|[\u1FD0-\u1FD3]|[\u1FD6-\u1FDB]|[\u1FE0-\u1FEC]|" +
|
73
|
+
"[\u1FF2-\u1FF4]|[\u1FF6-\u1FFC]|\u2126|[\u212A-\u212B]|\u212E|" +
|
74
|
+
"[\u2180-\u2182]|[\u3041-\u3094]|[\u30A1-\u30FA]|[\u3105-\u312C]|" +
|
75
|
+
"[\uAC00-\uD7A3]"
|
76
|
+
|
77
|
+
COMBINING_CHAR_PATTERN =
|
78
|
+
"[\u0300-\u0345]|[\u0360-\u0361]|[\u0483-\u0486]|[\u0591-\u05A1]|" +
|
79
|
+
"[\u05A3-\u05B9]|[\u05BB-\u05BD]|\u05BF|[\u05C1-\u05C2]|\u05C4|" +
|
80
|
+
"[\u064B-\u0652]|\u0670|[\u06D6-\u06DC]|[\u06DD-\u06DF]|" +
|
81
|
+
"[\u06E0-\u06E4]|[\u06E7-\u06E8]|[\u06EA-\u06ED]|[\u0901-\u0903]|" +
|
82
|
+
"\u093C|[\u093E-\u094C]|\u094D|[\u0951-\u0954]|[\u0962-\u0963]|" +
|
83
|
+
"[\u0981-\u0983]|\u09BC|\u09BE|\u09BF|[\u09C0-\u09C4]|" +
|
84
|
+
"[\u09C7-\u09C8]|[\u09CB-\u09CD]|\u09D7|[\u09E2-\u09E3]|\u0A02|" +
|
85
|
+
"\u0A3C|\u0A3E|\u0A3F|[\u0A40-\u0A42]|[\u0A47-\u0A48]|" +
|
86
|
+
"[\u0A4B-\u0A4D]|[\u0A70-\u0A71]|[\u0A81-\u0A83]|\u0ABC|" +
|
87
|
+
"[\u0ABE-\u0AC5]|[\u0AC7-\u0AC9]|[\u0ACB-\u0ACD]|[\u0B01-\u0B03]|" +
|
88
|
+
"\u0B3C|[\u0B3E-\u0B43]|[\u0B47-\u0B48]|[\u0B4B-\u0B4D]|" +
|
89
|
+
"[\u0B56-\u0B57]|[\u0B82-\u0B83]|[\u0BBE-\u0BC2]|[\u0BC6-\u0BC8]|" +
|
90
|
+
"[\u0BCA-\u0BCD]|\u0BD7|[\u0C01-\u0C03]|[\u0C3E-\u0C44]|" +
|
91
|
+
"[\u0C46-\u0C48]|[\u0C4A-\u0C4D]|[\u0C55-\u0C56]|[\u0C82-\u0C83]|" +
|
92
|
+
"[\u0CBE-\u0CC4]|[\u0CC6-\u0CC8]|[\u0CCA-\u0CCD]|[\u0CD5-\u0CD6]|" +
|
93
|
+
"[\u0D02-\u0D03]|[\u0D3E-\u0D43]|[\u0D46-\u0D48]|[\u0D4A-\u0D4D]|" +
|
94
|
+
"\u0D57|\u0E31|[\u0E34-\u0E3A]|[\u0E47-\u0E4E]|\u0EB1|" +
|
95
|
+
"[\u0EB4-\u0EB9]|[\u0EBB-\u0EBC]|[\u0EC8-\u0ECD]|[\u0F18-\u0F19]|" +
|
96
|
+
"\u0F35|\u0F37|\u0F39|\u0F3E|\u0F3F|[\u0F71-\u0F84]|" +
|
97
|
+
"[\u0F86-\u0F8B]|[\u0F90-\u0F95]|\u0F97|[\u0F99-\u0FAD]|" +
|
98
|
+
"[\u0FB1-\u0FB7]|\u0FB9|[\u20D0-\u20DC]|\u20E1|[\u302A-\u302F]|" +
|
99
|
+
"\u3099|\u309A"
|
100
|
+
|
101
|
+
DIGIT_PATTERN =
|
102
|
+
"[\u0030-\u0039]|[\u0660-\u0669]|[\u06F0-\u06F9]|"+
|
103
|
+
"[\u0966-\u096F]|[\u09E6-\u09EF]|[\u0A66-\u0A6F]|"+
|
104
|
+
"[\u0AE6-\u0AEF]|[\u0B66-\u0B6F]|[\u0BE7-\u0BEF]|"+
|
105
|
+
"[\u0C66-\u0C6F]|[\u0CE6-\u0CEF]|[\u0D66-\u0D6F]|"+
|
106
|
+
"[\u0E50-\u0E59]|[\u0ED0-\u0ED9]|[\u0F20-\u0F29]"
|
107
|
+
|
108
|
+
EXTENDER_PATTERN =
|
109
|
+
"\u00B7|\u02D0|\u02D1|\u0387|\u0640|\u0E46|\u0EC6|\u3005|" +
|
110
|
+
"[\u3031-\u3035]|[\u309D-\u309E]|[\u30FC-\u30FE]"
|
111
|
+
|
112
|
+
IDEOGRAPHIC_PATTERN = "[\u4E00-\u9FA5]|\u3007|[\u3021-\u3029]"
|
113
|
+
|
114
|
+
LETTER_PATTERN = BASE_CHAR_PATTERN + "|" + IDEOGRAPHIC_PATTERN
|
115
|
+
|
116
|
+
NAME_CHAR_PATTERN =
|
117
|
+
LETTER_PATTERN + "|" +
|
118
|
+
DIGIT_PATTERN + "|" +
|
119
|
+
"'.'|'-'|'_'|':'|" +
|
120
|
+
COMBINING_CHAR_PATTERN + "|" +
|
121
|
+
EXTENDER_PATTERN
|
122
|
+
|
123
|
+
# Element and attribute names must be name tokens.
|
124
|
+
# This is a regular expression used to determine whether a given string
|
125
|
+
# is a valid XML "name token" using only Latin characters.
|
126
|
+
LATIN_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9\-_\.]*$/
|
127
|
+
|
128
|
+
# Element and attribute names must be name tokens.
|
129
|
+
# This is a regular expression used to determine whether a given string
|
130
|
+
# is a valid XML "name token" using any valid Unicode characters.
|
131
|
+
FULL_NAME_PATTERN = /^(#{LETTER_PATTERN}|'_')(#{NAME_CHAR_PATTERN})*$/
|
132
|
+
|
27
133
|
XMLSCHEMA_INSTANCE_NS = "http://www.w3.org/1999/XMLSchema-instance"
|
28
134
|
|
29
135
|
# Escapes special characters in XML text.
|
@@ -57,15 +163,36 @@ module XMLUtil
|
|
57
163
|
end
|
58
164
|
|
59
165
|
# Determines whether given text is a name token.
|
60
|
-
def self.
|
166
|
+
def self.is_name(text)
|
61
167
|
return false if text == nil
|
62
|
-
|
168
|
+
|
169
|
+
# Names that start with "XML" in any case are reserved.
|
170
|
+
return false if text.downcase =~ /$xml/
|
171
|
+
|
172
|
+
# First attempt to match against the simpler regular expression
|
173
|
+
# for names that only use Latin characters
|
174
|
+
# because this should be faster and the most common case.
|
175
|
+
return true if (LATIN_NAME_PATTERN =~ text) != nil
|
176
|
+
|
177
|
+
# Since that didn't match, try the full regular expression.
|
178
|
+
# Ruby 1.8 doesn't support Unicode in regular expressions!
|
179
|
+
# Save this code for Ruby 1.9.
|
180
|
+
#matched_full = (FULL_NAME_PATTERN =~ text) != nil
|
181
|
+
#puts "#{text} matched full? #{matched_full}"
|
182
|
+
#matched_letter = (/^(#{LETTER_PATTERN}|'_')/ =~ text) != nil
|
183
|
+
#puts "#{text} matched letter? #{matched_letter}"
|
184
|
+
|
185
|
+
false
|
63
186
|
end
|
64
187
|
|
65
188
|
# Determines whether given text is a URI.
|
66
189
|
def self.is_uri(text)
|
67
|
-
|
68
|
-
|
190
|
+
begin
|
191
|
+
uri = URI.parse(text)
|
192
|
+
true
|
193
|
+
rescue URI::InvalidURIError
|
194
|
+
false
|
195
|
+
end
|
69
196
|
end
|
70
197
|
|
71
198
|
# Determines whether given text is a valid XML version.
|
@@ -83,8 +210,8 @@ module XMLUtil
|
|
83
210
|
|
84
211
|
# Verifies that the given text is a valid name token
|
85
212
|
# and raises an ArgumentError if it isn't.
|
86
|
-
def self.
|
87
|
-
unless
|
213
|
+
def self.verify_name(text)
|
214
|
+
unless is_name(text)
|
88
215
|
raise ArgumentError, "\"#{text}\" is an invalid NMTOKEN"
|
89
216
|
end
|
90
217
|
end
|
@@ -105,4 +232,4 @@ module XMLUtil
|
|
105
232
|
end
|
106
233
|
end
|
107
234
|
|
108
|
-
end
|
235
|
+
end
|
data/test/test_wax.rb
CHANGED
@@ -41,14 +41,25 @@ class WAXTest < Test::Unit::TestCase
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_attributes
|
44
|
-
WAX.write do
|
45
|
-
set_indent nil
|
44
|
+
wax = WAX.write do
|
46
45
|
start 'root'
|
46
|
+
namespace 'foo', 'http://www.ociweb.com/foo'
|
47
47
|
attr 'a1', 'v1'
|
48
48
|
attr 'a2', 2
|
49
|
+
attr 'foo', 'a3', 'bar'
|
50
|
+
attr 'foo', 'a4', 'baz', true
|
49
51
|
end
|
50
52
|
|
51
|
-
|
53
|
+
cr = wax.get_cr
|
54
|
+
xml =
|
55
|
+
'<root' + cr +
|
56
|
+
' xmlns:foo="http://www.ociweb.com/foo"' + cr +
|
57
|
+
' a1="v1"' + cr +
|
58
|
+
' a2="2"' + cr +
|
59
|
+
' foo:a3="bar"' + cr +
|
60
|
+
' foo:a4="baz"/>'
|
61
|
+
|
62
|
+
assert_equal xml, @sio.string
|
52
63
|
end
|
53
64
|
|
54
65
|
def test_bad_attribute_name
|
@@ -121,6 +132,15 @@ class WAXTest < Test::Unit::TestCase
|
|
121
132
|
end
|
122
133
|
end
|
123
134
|
|
135
|
+
def test_bad_dtd_multiple
|
136
|
+
assert_raise(RuntimeError) do
|
137
|
+
WAX.write do
|
138
|
+
dtd "one.dtd"
|
139
|
+
dtd "two.dtd" # can't specify two DTDs
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
124
144
|
def test_bad_element_name
|
125
145
|
assert_raise(ArgumentError) do
|
126
146
|
WAX.write { start "1root" }
|
@@ -159,6 +179,12 @@ class WAXTest < Test::Unit::TestCase
|
|
159
179
|
end
|
160
180
|
end
|
161
181
|
|
182
|
+
def test_bad_indent_datatype
|
183
|
+
assert_raise(ArgumentError) do
|
184
|
+
WAX.write { set_indent Time.now } # invalid type of object
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
162
188
|
def test_bad_namespace_duplicate_prefix
|
163
189
|
assert_raise(ArgumentError) do
|
164
190
|
# Can't define same namespace prefix more than once in the same scope.
|
@@ -228,8 +254,17 @@ class WAXTest < Test::Unit::TestCase
|
|
228
254
|
end
|
229
255
|
end
|
230
256
|
|
257
|
+
def test_bad_xslt_multiple
|
258
|
+
assert_raise(RuntimeError) do
|
259
|
+
WAX.write do
|
260
|
+
xslt "one.xslt"
|
261
|
+
xslt "two.xstl" # can't specify two XSLTs
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
231
266
|
def test_big
|
232
|
-
WAX.write do
|
267
|
+
wax = WAX.write do
|
233
268
|
start "root"
|
234
269
|
nl_text "text #1"
|
235
270
|
child "child1", "text"
|
@@ -240,69 +275,112 @@ class WAXTest < Test::Unit::TestCase
|
|
240
275
|
nl_text "text #3"
|
241
276
|
end
|
242
277
|
|
243
|
-
|
244
|
-
|
245
|
-
"
|
246
|
-
" text
|
247
|
-
"
|
248
|
-
"
|
278
|
+
cr = wax.get_cr
|
279
|
+
xml = "<root>" + cr +
|
280
|
+
" text #1" + cr +
|
281
|
+
" <child1>text</child1>" + cr +
|
282
|
+
" text #2" + cr +
|
283
|
+
" <child2 a1=\"v1\"/>" + cr +
|
284
|
+
" text #3" + cr +
|
249
285
|
"</root>"
|
250
286
|
|
251
287
|
assert_equal xml, @sio.string
|
252
288
|
end
|
253
289
|
|
254
290
|
def test_blank_line
|
255
|
-
WAX.write do
|
291
|
+
wax = WAX.write do
|
256
292
|
start "root"
|
257
293
|
blank_line
|
258
294
|
end
|
259
295
|
|
296
|
+
cr = wax.get_cr
|
260
297
|
xml =
|
261
|
-
"<root
|
262
|
-
"
|
298
|
+
"<root>" + cr +
|
299
|
+
"" + cr +
|
263
300
|
"</root>"
|
264
301
|
assert_equal xml, @sio.string
|
265
302
|
end
|
266
303
|
|
267
304
|
def test_cdata
|
268
|
-
WAX.write do
|
305
|
+
wax = WAX.write do
|
269
306
|
start "root"
|
270
307
|
cdata "1<2>3&4'5\"6"
|
271
308
|
end
|
272
309
|
|
310
|
+
cr = wax.get_cr
|
273
311
|
xml =
|
274
|
-
"<root
|
275
|
-
" <![CDATA[1<2>3&4'5\"6]]
|
312
|
+
"<root>" + cr +
|
313
|
+
" <![CDATA[1<2>3&4'5\"6]]>" + cr +
|
276
314
|
"</root>"
|
277
315
|
assert_equal xml, @sio.string
|
278
316
|
end
|
279
317
|
|
280
318
|
def test_comment
|
281
|
-
WAX.write do
|
319
|
+
wax = WAX.write do
|
282
320
|
comment "comment #1"
|
283
321
|
comment "comment #2"
|
284
322
|
start "root"
|
285
323
|
comment "comment #3"
|
286
324
|
end
|
287
325
|
|
326
|
+
cr = wax.get_cr
|
288
327
|
xml =
|
289
|
-
"<!-- comment #1
|
290
|
-
"<!-- comment #2
|
291
|
-
"<root
|
292
|
-
" <!-- comment #3
|
328
|
+
"<!-- comment #1 -->" + cr +
|
329
|
+
"<!-- comment #2 -->" + cr +
|
330
|
+
"<root>" + cr +
|
331
|
+
" <!-- comment #3 -->" + cr +
|
293
332
|
"</root>"
|
294
333
|
|
295
334
|
assert_equal xml, @sio.string
|
296
335
|
end
|
297
336
|
|
337
|
+
def test_commented_start
|
338
|
+
wax = WAX.write do
|
339
|
+
start 'root'
|
340
|
+
commented_start 'child'
|
341
|
+
child 'grandchild', 'some text'
|
342
|
+
end
|
343
|
+
|
344
|
+
cr = wax.get_cr
|
345
|
+
xml =
|
346
|
+
"<root>" + cr +
|
347
|
+
" <!--child>" + cr +
|
348
|
+
" <grandchild>some text</grandchild>" + cr +
|
349
|
+
" </child-->" + cr +
|
350
|
+
"</root>";
|
351
|
+
|
352
|
+
assert_equal xml, @sio.string
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_commented_start_with_namespace
|
356
|
+
wax = WAX.write do
|
357
|
+
start 'root'
|
358
|
+
namespace 'foo', 'http://www.ociweb.com/foo'
|
359
|
+
commented_start 'foo', 'child'
|
360
|
+
child 'grandchild', 'some text'
|
361
|
+
end
|
362
|
+
|
363
|
+
cr = wax.get_cr
|
364
|
+
xml =
|
365
|
+
'<root' + cr +
|
366
|
+
' xmlns:foo="http://www.ociweb.com/foo">' + cr +
|
367
|
+
' <!--foo:child>' + cr +
|
368
|
+
' <grandchild>some text</grandchild>' + cr +
|
369
|
+
' </foo:child-->' + cr +
|
370
|
+
'</root>';
|
371
|
+
|
372
|
+
assert_equal xml, @sio.string
|
373
|
+
end
|
374
|
+
|
298
375
|
def test_dtd
|
299
|
-
WAX.write do
|
376
|
+
wax = WAX.write do
|
300
377
|
dtd "http://www.ociweb.com/xml/root.dtd"
|
301
378
|
start "root"
|
302
379
|
end
|
303
380
|
|
381
|
+
cr = wax.get_cr
|
304
382
|
xml =
|
305
|
-
"<!DOCTYPE root SYSTEM \"http://www.ociweb.com/xml/root.dtd\"
|
383
|
+
"<!DOCTYPE root SYSTEM \"http://www.ociweb.com/xml/root.dtd\">" + cr +
|
306
384
|
"<root/>"
|
307
385
|
|
308
386
|
assert_equal xml, @sio.string
|
@@ -310,7 +388,7 @@ class WAXTest < Test::Unit::TestCase
|
|
310
388
|
|
311
389
|
def test_empty
|
312
390
|
WAX.write do
|
313
|
-
|
391
|
+
no_indents_or_crs
|
314
392
|
start "root"
|
315
393
|
end
|
316
394
|
|
@@ -319,7 +397,7 @@ class WAXTest < Test::Unit::TestCase
|
|
319
397
|
|
320
398
|
def test_entity_def
|
321
399
|
WAX.write do
|
322
|
-
|
400
|
+
no_indents_or_crs
|
323
401
|
entity_def "name", "value"
|
324
402
|
start "root"
|
325
403
|
end
|
@@ -330,7 +408,7 @@ class WAXTest < Test::Unit::TestCase
|
|
330
408
|
|
331
409
|
def test_external_entity_def
|
332
410
|
WAX.write do
|
333
|
-
|
411
|
+
no_indents_or_crs
|
334
412
|
external_entity_def "name", "value"
|
335
413
|
start "root"
|
336
414
|
end
|
@@ -341,7 +419,7 @@ class WAXTest < Test::Unit::TestCase
|
|
341
419
|
|
342
420
|
def test_escape
|
343
421
|
WAX.write do
|
344
|
-
|
422
|
+
no_indents_or_crs
|
345
423
|
start "root"
|
346
424
|
text "abc<def>ghi'jkl\"mno&pqr"
|
347
425
|
end
|
@@ -353,7 +431,7 @@ class WAXTest < Test::Unit::TestCase
|
|
353
431
|
def test_extra_end
|
354
432
|
assert_raise(RuntimeError) do
|
355
433
|
WAX.write do
|
356
|
-
|
434
|
+
no_indents_or_crs
|
357
435
|
start "root"
|
358
436
|
end!
|
359
437
|
end!
|
@@ -371,7 +449,7 @@ class WAXTest < Test::Unit::TestCase
|
|
371
449
|
wax.set_indent "\t"
|
372
450
|
assert_equal "\t", wax.get_indent
|
373
451
|
|
374
|
-
wax.
|
452
|
+
wax.no_indents_or_crs
|
375
453
|
assert_equal nil, wax.get_indent
|
376
454
|
|
377
455
|
wax.set_indent ""
|
@@ -379,30 +457,57 @@ class WAXTest < Test::Unit::TestCase
|
|
379
457
|
end
|
380
458
|
|
381
459
|
def test_indent_by_num
|
382
|
-
WAX.write do
|
460
|
+
wax = WAX.write do
|
383
461
|
set_indent 2
|
384
462
|
start "root"
|
385
463
|
child "child", "text"
|
386
464
|
end
|
387
465
|
|
388
|
-
|
466
|
+
cr = wax.get_cr
|
467
|
+
xml =
|
468
|
+
"<root>" + cr +
|
469
|
+
" <child>text</child>" + cr +
|
470
|
+
"</root>"
|
389
471
|
assert_equal xml, @sio.string
|
390
472
|
end
|
391
473
|
|
392
474
|
def test_indent_by_string
|
393
|
-
WAX.write do
|
394
|
-
set_indent "
|
475
|
+
wax = WAX.write do
|
476
|
+
set_indent " " # 1 space
|
395
477
|
start "root"
|
396
478
|
child "child", "text"
|
397
479
|
end
|
398
480
|
|
399
|
-
|
481
|
+
cr = wax.get_cr
|
482
|
+
xml =
|
483
|
+
"<root>" + cr +
|
484
|
+
" <child>text</child>" + cr +
|
485
|
+
"</root>"
|
400
486
|
assert_equal xml, @sio.string
|
401
487
|
end
|
402
488
|
|
489
|
+
def test_indent_by_string_weird
|
490
|
+
wax = WAX.new
|
491
|
+
|
492
|
+
# Can set indent to anything if "trust me" is true.
|
493
|
+
wax.set_trust_me(true)
|
494
|
+
indent = "abc"
|
495
|
+
wax.set_indent(indent) # weird indentation characters
|
496
|
+
wax.set_trust_me(false)
|
497
|
+
|
498
|
+
wax.start("root").child("child", "text").close();
|
499
|
+
|
500
|
+
cr = wax.get_cr
|
501
|
+
xml =
|
502
|
+
"<root>" + cr +
|
503
|
+
indent + "<child>text</child>" + cr +
|
504
|
+
"</root>";
|
505
|
+
assert_equal xml, @sio.string
|
506
|
+
end
|
507
|
+
|
403
508
|
def test_namespace
|
404
509
|
WAX.write do
|
405
|
-
|
510
|
+
no_indents_or_crs
|
406
511
|
start "root"
|
407
512
|
namespace "http://www.ociweb.com/tns1"
|
408
513
|
namespace "tns2", "http://www.ociweb.com/tns2"
|
@@ -418,7 +523,7 @@ class WAXTest < Test::Unit::TestCase
|
|
418
523
|
|
419
524
|
def test_no_indent
|
420
525
|
WAX.write do
|
421
|
-
|
526
|
+
no_indents_or_crs
|
422
527
|
start "root"
|
423
528
|
child "child", "text"
|
424
529
|
end
|
@@ -427,6 +532,12 @@ class WAXTest < Test::Unit::TestCase
|
|
427
532
|
assert_equal xml, @sio.string
|
428
533
|
end
|
429
534
|
|
535
|
+
def test_no_indent_or_crs
|
536
|
+
wax = WAX.new
|
537
|
+
wax.no_indents_or_crs
|
538
|
+
assert_equal nil, wax.get_indent
|
539
|
+
end
|
540
|
+
|
430
541
|
def test_no_root
|
431
542
|
assert_raise(RuntimeError) do
|
432
543
|
WAX.write {}
|
@@ -434,21 +545,22 @@ class WAXTest < Test::Unit::TestCase
|
|
434
545
|
end
|
435
546
|
|
436
547
|
def test_processing_instruction_in_prologue
|
437
|
-
WAX.write do
|
548
|
+
wax = WAX.write do
|
438
549
|
processing_instruction "xml-stylesheet",
|
439
550
|
"type=\"text/xsl\" href=\"http://www.ociweb.com/foo.xslt\""
|
440
551
|
start "root"
|
441
552
|
end
|
442
553
|
|
554
|
+
cr = wax.get_cr
|
443
555
|
xml =
|
444
|
-
"<?xml-stylesheet type=\"text/xsl\" href=\"http://www.ociweb.com/foo.xslt\"
|
556
|
+
"<?xml-stylesheet type=\"text/xsl\" href=\"http://www.ociweb.com/foo.xslt\"?>" + cr +
|
445
557
|
"<root/>"
|
446
558
|
assert_equal xml, @sio.string
|
447
559
|
end
|
448
560
|
|
449
561
|
def test_processing_instruction_after_prologue
|
450
562
|
WAX.write do
|
451
|
-
|
563
|
+
no_indents_or_crs
|
452
564
|
start "root"
|
453
565
|
processing_instruction "target", "data"
|
454
566
|
end
|
@@ -459,7 +571,7 @@ class WAXTest < Test::Unit::TestCase
|
|
459
571
|
|
460
572
|
def test_prefix
|
461
573
|
WAX.write do
|
462
|
-
|
574
|
+
no_indents_or_crs
|
463
575
|
start "foo", "root"
|
464
576
|
attr "bar", "baz"
|
465
577
|
# Note that the namespace is defined after it is used,
|
@@ -473,18 +585,19 @@ class WAXTest < Test::Unit::TestCase
|
|
473
585
|
end
|
474
586
|
|
475
587
|
def test_schemas_with_indent
|
476
|
-
WAX.write do
|
588
|
+
wax = WAX.write do
|
477
589
|
start "root"
|
478
590
|
namespace nil, "http://www.ociweb.com/tns1", "tns1.xsd"
|
479
591
|
namespace "tns2", "http://www.ociweb.com/tns2", "tns2.xsd"
|
480
592
|
end
|
481
593
|
|
482
|
-
|
483
|
-
|
484
|
-
" xmlns
|
485
|
-
" xmlns:
|
594
|
+
cr = wax.get_cr
|
595
|
+
xml = "<root" + cr +
|
596
|
+
" xmlns=\"http://www.ociweb.com/tns1\"" + cr +
|
597
|
+
" xmlns:tns2=\"http://www.ociweb.com/tns2\"" + cr +
|
598
|
+
" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"" + cr +
|
486
599
|
" xsi:schemaLocation=\"" +
|
487
|
-
"http://www.ociweb.com/tns1 tns1.xsd
|
600
|
+
"http://www.ociweb.com/tns1 tns1.xsd" + cr +
|
488
601
|
" http://www.ociweb.com/tns2 tns2.xsd" +
|
489
602
|
"\"/>"
|
490
603
|
assert_equal xml, @sio.string
|
@@ -492,7 +605,7 @@ class WAXTest < Test::Unit::TestCase
|
|
492
605
|
|
493
606
|
def test_schemas_without_indent
|
494
607
|
WAX.write do
|
495
|
-
|
608
|
+
no_indents_or_crs
|
496
609
|
start "root"
|
497
610
|
namespace nil, "http://www.ociweb.com/tns1", "tns1.xsd"
|
498
611
|
namespace "tns2", "http://www.ociweb.com/tns2", "tns2.xsd"
|
@@ -511,18 +624,22 @@ class WAXTest < Test::Unit::TestCase
|
|
511
624
|
|
512
625
|
def test_text
|
513
626
|
WAX.write do
|
514
|
-
|
627
|
+
no_indents_or_crs
|
515
628
|
start "root"
|
516
629
|
text "text"
|
517
630
|
end
|
518
631
|
|
519
|
-
|
632
|
+
xml = "<root>text</root>"
|
633
|
+
assert_equal xml, @sio.string
|
520
634
|
end
|
521
635
|
|
522
636
|
def test_trust_me_false
|
523
637
|
assert_raise(ArgumentError) do
|
638
|
+
this = self
|
524
639
|
WAX.write do
|
525
640
|
set_trust_me false
|
641
|
+
this.assert_equal false, is_trust_me
|
642
|
+
|
526
643
|
# Since error checking is turned on,
|
527
644
|
# element names must be valid and text is escaped.
|
528
645
|
start "123"
|
@@ -532,9 +649,13 @@ class WAXTest < Test::Unit::TestCase
|
|
532
649
|
end
|
533
650
|
|
534
651
|
def test_trust_me_true
|
652
|
+
this = self
|
535
653
|
WAX.write do
|
536
654
|
set_trust_me true
|
537
|
-
|
655
|
+
this.assert_equal true, is_trust_me
|
656
|
+
|
657
|
+
no_indents_or_crs
|
658
|
+
|
538
659
|
# Since error checking is turned off,
|
539
660
|
# invalid element names and unescaped text are allowed.
|
540
661
|
start "123"
|
@@ -544,10 +665,36 @@ class WAXTest < Test::Unit::TestCase
|
|
544
665
|
assert_equal "<123><>&'\"</123>", @sio.string
|
545
666
|
end
|
546
667
|
|
668
|
+
def test_use_non_windows_cr
|
669
|
+
wax = WAX.new
|
670
|
+
wax.use_non_windows_cr
|
671
|
+
assert_equal "\n", wax.get_cr
|
672
|
+
|
673
|
+
# Most of the other tests verify that
|
674
|
+
# this CR is actually used in the output.
|
675
|
+
end
|
676
|
+
|
677
|
+
def test_use_windows_cr
|
678
|
+
wax = WAX.write do
|
679
|
+
use_windows_cr
|
680
|
+
start "root"
|
681
|
+
child "child", "text"
|
682
|
+
end
|
683
|
+
|
684
|
+
cr = wax.get_cr
|
685
|
+
assert_equal "\r\n", cr
|
686
|
+
|
687
|
+
xml =
|
688
|
+
"<root>" + cr +
|
689
|
+
" <child>text</child>" + cr +
|
690
|
+
"</root>";
|
691
|
+
assert_equal xml, @sio.string
|
692
|
+
end
|
693
|
+
|
547
694
|
def test_write_file
|
548
695
|
file_path = "temp.xml"
|
549
696
|
WAX.write(file_path) do
|
550
|
-
|
697
|
+
no_indents_or_crs
|
551
698
|
start "root"
|
552
699
|
text "text"
|
553
700
|
end
|
@@ -556,14 +703,56 @@ class WAXTest < Test::Unit::TestCase
|
|
556
703
|
File.delete(file_path)
|
557
704
|
end
|
558
705
|
|
706
|
+
# Tests the instance version of the write method
|
707
|
+
# which is convenience for passing to methods
|
708
|
+
# that writes parts of the XML.
|
709
|
+
def test_write_instance
|
710
|
+
require 'address'
|
711
|
+
require 'person'
|
712
|
+
address = Address.new('123 Some Street', 'Some City', 'MO', 12345)
|
713
|
+
person = Person.new('R. Mark Volkmann', '4/16/1961', address)
|
714
|
+
wax = WAX.new
|
715
|
+
person.to_xml(wax)
|
716
|
+
wax.close
|
717
|
+
|
718
|
+
cr = wax.get_cr
|
719
|
+
xml =
|
720
|
+
"<person birthdate=\"4/16/1961\">" + cr +
|
721
|
+
" <name>R. Mark Volkmann</name>" + cr +
|
722
|
+
" <address>" + cr +
|
723
|
+
" <street>123 Some Street</street>" + cr +
|
724
|
+
" <city>Some City</city>" + cr +
|
725
|
+
" <state>MO</state>" + cr +
|
726
|
+
" <zip>12345</zip>" + cr +
|
727
|
+
" </address>" + cr +
|
728
|
+
"</person>"
|
729
|
+
assert_equal xml, @sio.string
|
730
|
+
end
|
731
|
+
|
559
732
|
def test_xml_declaration
|
560
|
-
WAX.write($stdout, "1.0") do
|
561
|
-
|
733
|
+
wax = WAX.write($stdout, "1.0") do
|
734
|
+
no_indents_or_crs
|
562
735
|
start "root"
|
563
736
|
end
|
564
737
|
|
565
|
-
|
738
|
+
cr = wax.get_cr
|
739
|
+
xml =
|
740
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + cr +
|
741
|
+
"<root/>"
|
566
742
|
assert_equal xml, @sio.string
|
567
743
|
end
|
568
|
-
|
569
|
-
|
744
|
+
|
745
|
+
def test_xslt
|
746
|
+
wax = WAX.write do
|
747
|
+
xslt "root.xslt"
|
748
|
+
start "root"
|
749
|
+
end
|
750
|
+
|
751
|
+
cr = wax.get_cr
|
752
|
+
xml =
|
753
|
+
"<?xml-stylesheet type=\"text/xsl\" href=\"root.xslt\"?>" + cr +
|
754
|
+
"<root/>"
|
755
|
+
|
756
|
+
assert_equal xml, @sio.string
|
757
|
+
end
|
758
|
+
end
|
data/test/test_xmlutil.rb
CHANGED
@@ -29,9 +29,9 @@ class XMLUtilTest < Test::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def test_bad_name
|
33
33
|
assert_raise(ArgumentError) do
|
34
|
-
XMLUtil.
|
34
|
+
XMLUtil.verify_name("1a")
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -41,11 +41,10 @@ class XMLUtilTest < Test::Unit::TestCase
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
# TODO: Uncomment after is_uri method is implemented.
|
45
44
|
def test_bad_uri
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
assert_raise(ArgumentError) do
|
46
|
+
XMLUtil.verify_uri(":junk")
|
47
|
+
end
|
49
48
|
end
|
50
49
|
|
51
50
|
def test_escape
|
@@ -65,15 +64,14 @@ class XMLUtilTest < Test::Unit::TestCase
|
|
65
64
|
assert !XMLUtil.is_comment("one two --")
|
66
65
|
end
|
67
66
|
|
68
|
-
def
|
69
|
-
assert XMLUtil.
|
70
|
-
assert !XMLUtil.
|
67
|
+
def test_is_name
|
68
|
+
assert XMLUtil.is_name("a1")
|
69
|
+
assert !XMLUtil.is_name("1a")
|
71
70
|
end
|
72
71
|
|
73
|
-
# TODO: Uncomment after is_uri method is implemented.
|
74
72
|
def test_is_uri
|
75
|
-
|
76
|
-
|
73
|
+
assert XMLUtil.is_uri("http://www.ociweb.com/foo")
|
74
|
+
assert !XMLUtil.is_uri(":junk")
|
77
75
|
end
|
78
76
|
|
79
77
|
def test_is_version
|
@@ -83,4 +81,4 @@ class XMLUtilTest < Test::Unit::TestCase
|
|
83
81
|
assert !XMLUtil.is_version("1.3")
|
84
82
|
end
|
85
83
|
|
86
|
-
end
|
84
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- R. Mark Volkmann
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-09-
|
12
|
+
date: 2008-09-15 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|