wax 0.9.5 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|