xml-mapping 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Rakefile +1 -5
- data/TODO.txt +2 -0
- data/examples/company_usage.intout +3 -3
- data/examples/documents_folders_usage.intout +2 -2
- data/examples/order_signature_enhanced_usage.intout +1 -1
- data/examples/order_usage.intout +9 -9
- data/examples/person.intout +3 -3
- data/examples/person_mm.intout +2 -2
- data/examples/publication.intout +2 -2
- data/examples/reader.intout +1 -1
- data/examples/stringarray_usage.intout +1 -1
- data/examples/time_augm.intout +6 -6
- data/examples/xpath_create_new.intout +11 -13
- data/examples/xpath_ensure_created.intout +2 -2
- data/examples/xpath_usage.intout +1 -1
- data/lib/xml/mapping/base.rb +14 -2
- data/lib/xml/mapping/standard_nodes.rb +11 -4
- data/lib/xml/mapping/version.rb +1 -1
- data/lib/xml/rexml_ext.rb +1 -1
- data/test/fixtures/number.xml +5 -0
- data/test/number.rb +11 -0
- data/test/xml_mapping_test.rb +41 -0
- data/user_manual.md +28 -28
- data/user_manual_xxpath.md +14 -16
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1d3c510b64931acb9fcd54695e9e594e87663da7dab9d052a19e52eb1feadd58
|
4
|
+
data.tar.gz: 1712f4e61dd043d89e18315773cba8a90b54c12b75259e197b58138680c917e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91bf0706631fb3bc90fbb36cf9ee4e49ff3a6c6223e22dc97770e516ac4e92237fc95f8e45a3ceabf03c4531d5f086cfb6718ab8895917c07a932a34577ed654
|
7
|
+
data.tar.gz: 447cf363db2974074a321a3caabc7aee7f0e824aff0ec2edbe0db158f7dd8aa69709575cbf48f3412c911347dfe58fd54879869faba3191db99937bd03927496
|
data/Rakefile
CHANGED
@@ -10,7 +10,6 @@ require 'rake/testtask'
|
|
10
10
|
require 'rdoc/task'
|
11
11
|
require 'rake/packagetask'
|
12
12
|
require 'rubygems/package_task'
|
13
|
-
require 'rake/contrib/sshpublisher'
|
14
13
|
|
15
14
|
require File.dirname(__FILE__)+"/lib/xml/mapping/version"
|
16
15
|
|
@@ -45,10 +44,7 @@ RDoc::Task.new do |rdoc|
|
|
45
44
|
rdoc.rdoc_files.include(*FILES_RDOC_EXTRA)
|
46
45
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
46
|
|
48
|
-
|
49
|
-
# this somewhat of a black art because RDocTask doesn't document the
|
50
|
-
# prerequisite of its rdoc task (<rdoc_dir>/index.html)
|
51
|
-
file "#{rdoc.rdoc_dir}/index.html" => (FileList.new("examples/**/*.rb") + FILES_RDOC_INCLUDES)
|
47
|
+
task :rdoc => (FileList.new("examples/**/*.rb") + FILES_RDOC_INCLUDES)
|
52
48
|
end
|
53
49
|
|
54
50
|
|
data/TODO.txt
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
c = Company.load_from_file('company.xml')
|
2
|
-
=> #<Company:
|
2
|
+
=> #<Company:0x00007fa87c0251a8 @name="ACME inc.", @address=#<Address:0x00007fa87c869940 @city="Berlin", @zip=10113>, @customers=[#<Customer:0x00007fa87c843740 @id="jim", @name="James Kirk">, #<Customer:0x00007fa87b98e6c8 @id="ernie", @name="Ernie">, #<Customer:0x00007fa87babfbc8 @id="bert", @name="Bert">]>
|
3
3
|
c.name
|
4
4
|
=> "ACME inc."
|
5
5
|
c.customers.size
|
6
6
|
=> 3
|
7
7
|
c.customers[1]
|
8
|
-
=> #<Customer:
|
8
|
+
=> #<Customer:0x00007fa87b98e6c8 @id="ernie", @name="Ernie">
|
9
9
|
c.customers[1].name
|
10
10
|
=> "Ernie"
|
11
11
|
c.customers[0].name
|
@@ -13,7 +13,7 @@ c.customers[0].name
|
|
13
13
|
c.customers[0].name = 'James Tiberius Kirk'
|
14
14
|
=> "James Tiberius Kirk"
|
15
15
|
c.customers << Customer.new('cm','Cookie Monster')
|
16
|
-
=> [#<Customer:
|
16
|
+
=> [#<Customer:0x00007fa87c843740 @id="jim", @name="James Tiberius Kirk">, #<Customer:0x00007fa87b98e6c8 @id="ernie", @name="Ernie">, #<Customer:0x00007fa87babfbc8 @id="bert", @name="Bert">, #<Customer:0x00007fa87babd558 @id="cm", @name="Cookie Monster">]
|
17
17
|
xml2 = c.save_to_xml
|
18
18
|
=> <company name='ACME inc.'> ... </>
|
19
19
|
xml2.write($stdout,2)
|
@@ -1,10 +1,10 @@
|
|
1
1
|
|
2
2
|
root = XML::Mapping.load_object_from_file "documents_folders.xml"
|
3
|
-
=> #<Folder:
|
3
|
+
=> #<Folder:0x00007fa87c9362d8 @entries=[#<Document:0x00007fa87c935310 @name="plan", @contents=" inhale, exhale">, #<Folder:0x00007fa87c934758 @entries=[#<Folder:0x00007fa87c9639b8 @entries=[#<Document:0x00007fa87c961e88 @name="README", @contents="foo bar baz">], @name="xml-mapping">], @name="work">], @name="home">
|
4
4
|
root.name
|
5
5
|
=> "home"
|
6
6
|
root.entries
|
7
|
-
=> [#<Document:
|
7
|
+
=> [#<Document:0x00007fa87c935310 @name="plan", @contents=" inhale, exhale">, #<Folder:0x00007fa87c934758 @entries=[#<Folder:0x00007fa87c9639b8 @entries=[#<Document:0x00007fa87c961e88 @name="README", @contents="foo bar baz">], @name="xml-mapping">], @name="work">]
|
8
8
|
|
9
9
|
root.append "etc", Folder.new
|
10
10
|
root["etc"].append "passwd", Document.new
|
@@ -1,5 +1,5 @@
|
|
1
1
|
s=Signature.load_from_file("order_signature_enhanced.xml")
|
2
|
-
=> #<Signature:
|
2
|
+
=> #<Signature:0x00007fa87c919188 @position="product manager", @signed_on=2005-02-13 00:00:00 +0100, @name="John Doe">
|
3
3
|
s.signed_on
|
4
4
|
=> 2005-02-13 00:00:00 +0100
|
5
5
|
s.signed_on=Time.local(1976,12,18)
|
data/examples/order_usage.intout
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
####read access
|
2
2
|
o=Order.load_from_file("order.xml")
|
3
|
-
=> #<Order:
|
3
|
+
=> #<Order:0x00007fa87c968e68 @signatures=[#<Signature:0x00007fa87c970fc8 @position="product manager", @name="John Doe">, #<Signature:0x00007fa87c970500 @position="clerk", @name="Jill Smith">, #<Signature:0x00007fa87bacf8e8 @position="Some Employee", @name="Miles O'Brien">], @reference="12343-AHSHE-314159", @client=#<Client:0x00007fa87c968508 @work_address=#<Address:0x00007fa87babdcb0 @city="San Francisco", @state="CA", @zip=94102, @street="98765, Fulton Street">, @name="Jean Smith", @home_address=#<Address:0x00007fa87babf808 @city="San Mateo", @state="CA", @zip=94403, @street="2000, Alameda de las Pulgas">>, @items={"RF-0001"=>#<Item:0x00007fa87c973ea8 @descr="Stuffed Penguin", @quantity=10, @unit_price=8.95>, "RF-0034"=>#<Item:0x00007fa87c972e68 @descr="Chocolate", @quantity=5, @unit_price=28.5>, "RF-3341"=>#<Item:0x00007fa87c971f68 @descr="Cookie", @quantity=30, @unit_price=0.85>}>
|
4
4
|
o.reference
|
5
5
|
=> "12343-AHSHE-314159"
|
6
6
|
o.client
|
7
|
-
=> #<Client:
|
7
|
+
=> #<Client:0x00007fa87c968508 @work_address=#<Address:0x00007fa87babdcb0 @city="San Francisco", @state="CA", @zip=94102, @street="98765, Fulton Street">, @name="Jean Smith", @home_address=#<Address:0x00007fa87babf808 @city="San Mateo", @state="CA", @zip=94403, @street="2000, Alameda de las Pulgas">>
|
8
8
|
o.items.keys
|
9
9
|
=> ["RF-0001", "RF-0034", "RF-3341"]
|
10
10
|
o.items["RF-0034"].descr
|
@@ -12,7 +12,7 @@ o.items["RF-0034"].descr
|
|
12
12
|
o.items["RF-0034"].total_price
|
13
13
|
=> 142.5
|
14
14
|
o.signatures
|
15
|
-
=> [#<Signature:
|
15
|
+
=> [#<Signature:0x00007fa87c970fc8 @position="product manager", @name="John Doe">, #<Signature:0x00007fa87c970500 @position="clerk", @name="Jill Smith">, #<Signature:0x00007fa87bacf8e8 @position="Some Employee", @name="Miles O'Brien">]
|
16
16
|
o.signatures[2].name
|
17
17
|
=> "Miles O'Brien"
|
18
18
|
o.signatures[2].position
|
@@ -150,17 +150,17 @@ xml.write($stdout,2)
|
|
150
150
|
|
151
151
|
####Starting a new order from scratch
|
152
152
|
o = Order.new
|
153
|
-
=> #<Order:
|
153
|
+
=> #<Order:0x00007fa87c94f328 @signatures=[]>
|
154
154
|
## attributes with default values (here: signatures) are set
|
155
155
|
## automatically
|
156
156
|
|
157
157
|
xml=o.save_to_xml
|
158
158
|
XML::MappingError: no value, and no default value, for attribute: reference
|
159
|
-
from /
|
160
|
-
from /
|
161
|
-
from /
|
162
|
-
from /
|
163
|
-
from /
|
159
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:724:in `obj_to_xml'
|
160
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:218:in `block in fill_into_xml'
|
161
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:217:in `each'
|
162
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:217:in `fill_into_xml'
|
163
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:229:in `save_to_xml'
|
164
164
|
## can't save as long as there are still unset attributes without
|
165
165
|
## default values
|
166
166
|
|
data/examples/person.intout
CHANGED
@@ -10,13 +10,13 @@ end
|
|
10
10
|
### usage
|
11
11
|
|
12
12
|
p1 = Person.load_from_xml(REXML::Document.new('<person name="Jim"/>').root)
|
13
|
-
=> #<Person:
|
13
|
+
=> #<Person:0x00007fa87bb3a6e8 @name="Jim">
|
14
14
|
|
15
15
|
p2 = Person.load_from_xml(REXML::Document.new('<person><name>James</name></person>').root)
|
16
|
-
=> #<Person:
|
16
|
+
=> #<Person:0x00007fa87ba83b50 @name="James">
|
17
17
|
|
18
18
|
p3 = Person.load_from_xml(REXML::Document.new('<person>Suzy</person>').root)
|
19
|
-
=> #<Person:
|
19
|
+
=> #<Person:0x00007fa87bb43ef0 @name="Suzy">
|
20
20
|
|
21
21
|
|
22
22
|
p1.save_to_xml.write($stdout)
|
data/examples/person_mm.intout
CHANGED
@@ -66,7 +66,7 @@ xml = REXML::Document.new('
|
|
66
66
|
|
67
67
|
## load using the default mapping
|
68
68
|
p = Person.load_from_xml xml
|
69
|
-
=> #<Person:
|
69
|
+
=> #<Person:0x00007fa87ba674c8 @name="Suzy", @age=28, @address=#<Address:0x00007fa87ba65dd0 @street="Abbey Road", @number=72, @city="London", @zip=18827>>
|
70
70
|
|
71
71
|
## save using the default mapping
|
72
72
|
xml2 = p.save_to_xml
|
@@ -109,6 +109,6 @@ other_xml.write $stdout,2
|
|
109
109
|
</individual>
|
110
110
|
## load it again using the :other mapping
|
111
111
|
p2 = Person.load_from_xml other_xml, :mapping=>:other
|
112
|
-
=> #<Person:
|
112
|
+
=> #<Person:0x00007fa87c0b3f98 @name="Suzy", @age=28, @address=#<Address:0x00007fa87c0b3638 @street="Abbey Road", @number=72, @city="London", @zip=18827>>
|
113
113
|
|
114
114
|
## p2 identical to p
|
data/examples/publication.intout
CHANGED
@@ -9,7 +9,7 @@ end
|
|
9
9
|
### usage
|
10
10
|
|
11
11
|
p1 = Publication.load_from_xml(REXML::Document.new('<publication author="Jim"/>').root)
|
12
|
-
=> #<Publication:
|
12
|
+
=> #<Publication:0x00007fa87c9b95e8 @author="Jim">
|
13
13
|
|
14
14
|
p2 = Publication.load_from_xml(REXML::Document.new('
|
15
15
|
<publication>
|
@@ -17,4 +17,4 @@ p2 = Publication.load_from_xml(REXML::Document.new('
|
|
17
17
|
<contr>Mel</contr>
|
18
18
|
<contr>Toby</contr>
|
19
19
|
</publication>').root)
|
20
|
-
=> #<Publication:
|
20
|
+
=> #<Publication:0x00007fa87c0b5d48 @contributors=["Chris", "Mel", "Toby"]>
|
data/examples/reader.intout
CHANGED
data/examples/time_augm.intout
CHANGED
@@ -15,21 +15,21 @@ nowxml=Time.now.save_to_xml
|
|
15
15
|
nowxml.write($stdout,2)
|
16
16
|
<time>
|
17
17
|
<year>
|
18
|
-
|
18
|
+
2018
|
19
19
|
</year>
|
20
20
|
<month>
|
21
|
-
|
21
|
+
2
|
22
22
|
</month>
|
23
23
|
<mday>
|
24
|
-
|
24
|
+
28
|
25
25
|
</mday>
|
26
26
|
<hours>
|
27
|
-
|
27
|
+
16
|
28
28
|
</hours>
|
29
29
|
<minutes>
|
30
|
-
|
30
|
+
3
|
31
31
|
</minutes>
|
32
32
|
<seconds>
|
33
|
-
|
33
|
+
33
|
34
34
|
</seconds>
|
35
35
|
</time>
|
@@ -64,7 +64,7 @@ firstbazelt=XML::XXPath.new("/bar/baz").first(rootelt)
|
|
64
64
|
path2=XML::XXPath.new("@key2")
|
65
65
|
|
66
66
|
path2.create_new(firstbazelt)
|
67
|
-
=> #<XML::XXPath::Accessors::Attribute:
|
67
|
+
=> #<XML::XXPath::Accessors::Attribute:0x00007fa87bbf3698 @parent=<baz key='work' key2='[unset]'> ... </>, @name="key2">
|
68
68
|
d.write($stdout,2)
|
69
69
|
|
70
70
|
<foo>
|
@@ -87,12 +87,11 @@ d.write($stdout,2)
|
|
87
87
|
### same call again...
|
88
88
|
path2.create_new(firstbazelt)
|
89
89
|
XML::XXPathError: XPath (@key2): create_new and attribute already exists
|
90
|
-
from /
|
91
|
-
from /
|
92
|
-
from /
|
93
|
-
from /
|
94
|
-
from /
|
95
|
-
from /home/olaf/xml-mapping/lib/xml/xxpath.rb:112:in `create_new'
|
90
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath/steps.rb:215:in `create_on'
|
91
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath/steps.rb:80:in `block in creator'
|
92
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:91:in `all'
|
93
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:70:in `first'
|
94
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:112:in `create_new'
|
96
95
|
### can't create that path anew again -- an element can't have more
|
97
96
|
### than one attribute with the same name
|
98
97
|
|
@@ -150,12 +149,11 @@ d.write($stdout,2)
|
|
150
149
|
|
151
150
|
XML::XXPath.new("baz[6]").create_new(baz6elt.parent)
|
152
151
|
XML::XXPathError: XPath: baz[6]: create_new and element already exists
|
153
|
-
from /
|
154
|
-
from /
|
155
|
-
from /
|
156
|
-
from /
|
157
|
-
from /
|
158
|
-
from /home/olaf/xml-mapping/lib/xml/xxpath.rb:112:in `create_new'
|
152
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath/steps.rb:167:in `create_on'
|
153
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath/steps.rb:80:in `block in creator'
|
154
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:91:in `all'
|
155
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:70:in `first'
|
156
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:112:in `create_new'
|
159
157
|
### yep, baz[6] already existed and thus couldn't be created once
|
160
158
|
### again
|
161
159
|
|
@@ -96,7 +96,7 @@ d.write($stdout,2)
|
|
96
96
|
</foo>### no change
|
97
97
|
|
98
98
|
XML::XXPath.new("/bar/baz[6]/@haha").first(rootelt,:ensure_created=>true)
|
99
|
-
=> #<XML::XXPath::Accessors::Attribute:
|
99
|
+
=> #<XML::XXPath::Accessors::Attribute:0x00007fa87c9d32e0 @parent=<baz haha='[unset]'/>, @name="haha">
|
100
100
|
d.write($stdout,2)
|
101
101
|
|
102
102
|
<foo>
|
@@ -115,7 +115,7 @@ d.write($stdout,2)
|
|
115
115
|
</foo>### for there to be a 6th "baz" element, there must be 1st..5th "baz" elements
|
116
116
|
|
117
117
|
XML::XXPath.new("/bar/baz[6]/@haha").first(rootelt,:ensure_created=>true)
|
118
|
-
=> #<XML::XXPath::Accessors::Attribute:
|
118
|
+
=> #<XML::XXPath::Accessors::Attribute:0x00007fa87b0ee068 @parent=<baz haha='[unset]'/>, @name="haha">
|
119
119
|
d.write($stdout,2)
|
120
120
|
|
121
121
|
<foo>
|
data/examples/xpath_usage.intout
CHANGED
@@ -44,7 +44,7 @@ path2.all(d)
|
|
44
44
|
## "first" raises XML::XXPathError in such cases...
|
45
45
|
path2.first(d)
|
46
46
|
XML::XXPathError: path not found: /foo/bar[2]/baz[4]
|
47
|
-
from /
|
47
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:75:in `first'
|
48
48
|
|
49
49
|
##...unless we allow nil returns
|
50
50
|
path2.first(d,:allow_nil=>true)
|
data/lib/xml/mapping/base.rb
CHANGED
@@ -85,7 +85,7 @@ module XML
|
|
85
85
|
# can't really use a class variable for this because it must be
|
86
86
|
# shared by all class methods mixed into classes by including
|
87
87
|
# Mapping. See
|
88
|
-
# http://
|
88
|
+
# http://multi-io.github.io/mydocs-pub/ruby/mixin_class_methods_global_state.txt.html
|
89
89
|
# for a more detailed discussion.
|
90
90
|
Classes_by_rootelt_names = {} #:nodoc:
|
91
91
|
class << Classes_by_rootelt_names
|
@@ -258,8 +258,9 @@ module XML
|
|
258
258
|
# The XML is obtained by calling #save_to_xml.
|
259
259
|
def save_to_file(filename, options={:mapping=>:_default})
|
260
260
|
xml = save_to_xml :mapping=>options[:mapping]
|
261
|
+
formatter = options[:formatter] || self.class.mapping_output_formatter
|
261
262
|
File.open(filename,"w") do |f|
|
262
|
-
|
263
|
+
formatter.write(xml, f)
|
263
264
|
end
|
264
265
|
end
|
265
266
|
|
@@ -435,6 +436,17 @@ module XML
|
|
435
436
|
self.name.split('::')[-1].gsub(/^(.)/){$1.downcase}.gsub(/(.)([A-Z])/){$1+"-"+$2.downcase}
|
436
437
|
end
|
437
438
|
|
439
|
+
# the formatter to be used for output formatting when writing
|
440
|
+
# xml to character streams (Files/IOs). Combined
|
441
|
+
# getter/setter. Defaults to simple (compact/no-whitespace)
|
442
|
+
# formatting, may be overridden on a per-call base via options
|
443
|
+
def mapping_output_formatter(formatter=nil)
|
444
|
+
# TODO make it per-mapping
|
445
|
+
if formatter
|
446
|
+
@mapping_output_formatter = formatter
|
447
|
+
end
|
448
|
+
@mapping_output_formatter ||= REXML::Formatters::Default.new
|
449
|
+
end
|
438
450
|
end
|
439
451
|
|
440
452
|
|
@@ -48,14 +48,21 @@ module XML
|
|
48
48
|
@path = XML::XXPath.new(path)
|
49
49
|
args
|
50
50
|
end
|
51
|
+
|
51
52
|
def extract_attr_value(xml) # :nodoc:
|
52
53
|
txt = default_when_xpath_err{ @path.first(xml).text }
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
|
55
|
+
if txt.nil?
|
56
|
+
raise NoAttrValueSet, "Attribute #{@attrname} not set (text missing)"
|
57
|
+
else
|
58
|
+
begin
|
59
|
+
Integer(txt)
|
60
|
+
rescue ArgumentError
|
61
|
+
Float(txt)
|
62
|
+
end
|
57
63
|
end
|
58
64
|
end
|
65
|
+
|
59
66
|
def set_attr_value(xml, value) # :nodoc:
|
60
67
|
raise RuntimeError, "Not an integer: #{value}" unless Numeric===value
|
61
68
|
@path.first(xml,:ensure_created=>true).text = value.to_s
|
data/lib/xml/mapping/version.rb
CHANGED
data/lib/xml/rexml_ext.rb
CHANGED
data/test/number.rb
ADDED
data/test/xml_mapping_test.rb
CHANGED
@@ -46,6 +46,22 @@ class XmlMappingTest < Test::Unit::TestCase
|
|
46
46
|
assert_equal 18, @c.offices[1].address.number
|
47
47
|
end
|
48
48
|
|
49
|
+
def test_int_node_default_value
|
50
|
+
require 'number'
|
51
|
+
xml = REXML::Document.new(File.new(File.dirname(__FILE__) + "/fixtures/number.xml"))
|
52
|
+
|
53
|
+
assert_raise(XML::MappingError.new('no value, and no default value: Attribute value not set (text missing)')) do
|
54
|
+
Number.load_from_xml(xml.root, :mapping => :no_default)
|
55
|
+
end
|
56
|
+
|
57
|
+
num = nil
|
58
|
+
assert_nothing_raised do
|
59
|
+
num = Number.load_from_xml(xml.root, :mapping => :with_default)
|
60
|
+
end
|
61
|
+
|
62
|
+
assert_equal 0, num.value
|
63
|
+
end
|
64
|
+
|
49
65
|
def test_getter_boolean_node
|
50
66
|
path=XML::XXPath.new("offices/office[2]/classified")
|
51
67
|
assert_equal(path.first(@xml.root).text == "yes",
|
@@ -356,4 +372,29 @@ class XmlMappingTest < Test::Unit::TestCase
|
|
356
372
|
assert_equal 'no', xml2.root.elements[5].elements[3].elements[1].text
|
357
373
|
end
|
358
374
|
|
375
|
+
|
376
|
+
def test_file_io
|
377
|
+
require 'tmpdir'
|
378
|
+
Dir.mktmpdir do |dir|
|
379
|
+
@c.save_to_file "#{dir}/out.xml"
|
380
|
+
c2 = Company.load_from_file "#{dir}/out.xml"
|
381
|
+
assert_equal @c, c2, 'read back object equals original'
|
382
|
+
|
383
|
+
@c.save_to_file "#{dir}/out_default.xml", :formatter=>REXML::Formatters::Default.new
|
384
|
+
|
385
|
+
assert FileUtils.compare_file("#{dir}/out.xml", "#{dir}/out_default.xml"), 'default formatter is Formatters::Default'
|
386
|
+
assert File.open("#{dir}/out_default.xml").readlines.grep(/^\s/).empty?, 'default formatter produces no indentations'
|
387
|
+
|
388
|
+
@c.save_to_file "#{dir}/out_pretty.xml", :formatter=>REXML::Formatters::Pretty.new
|
389
|
+
assert not(File.open("#{dir}/out_pretty.xml").readlines.grep(/^\s/).empty?), 'pretty formatter does produce indentations'
|
390
|
+
|
391
|
+
Company.class_eval <<-EOS
|
392
|
+
mapping_output_formatter REXML::Formatters::Pretty.new
|
393
|
+
EOS
|
394
|
+
|
395
|
+
@c.save_to_file "#{dir}/out2.xml"
|
396
|
+
assert FileUtils.compare_file("#{dir}/out2.xml", "#{dir}/out_pretty.xml"), 'default formatter can be changed on a per-class basis'
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
359
400
|
end
|
data/user_manual.md
CHANGED
@@ -15,10 +15,10 @@ https://github.com/multi-io/xml-mapping
|
|
15
15
|
- {Single-attribute Nodes}[rdoc-label:label-Single-attribute+Nodes]
|
16
16
|
- {Default Values}[rdoc-label:label-Default+Values]
|
17
17
|
- {Single-attribute Nodes with Sub-objects}[rdoc-label:label-Single-attribute+Nodes+with+Sub-objects]
|
18
|
-
- {Attribute Handling Details, Augmenting Existing Classes}[rdoc-label:label-Attribute+Handling+Details
|
18
|
+
- {Attribute Handling Details, Augmenting Existing Classes}[rdoc-label:label-Attribute+Handling+Details-2C+Augmenting+Existing+Classes]
|
19
19
|
- {Other Nodes}[rdoc-label:label-Other+Nodes]
|
20
20
|
- {choice_node}[rdoc-label:label-choice_node]
|
21
|
-
- {Readers/Writers}[rdoc-label:label-Readers
|
21
|
+
- {Readers/Writers}[rdoc-label:label-Readers-2FWriters]
|
22
22
|
- {Multiple Mappings per Class}[rdoc-label:label-Multiple+Mappings+per+Class]
|
23
23
|
- {Defining your own Node Types}[rdoc-label:label-Defining+your+own+Node+Types]
|
24
24
|
- {XPath Interpreter}[rdoc-label:label-XPath+Interpreter]
|
@@ -153,11 +153,11 @@ http://www.castor.org/xml-mapping.html)
|
|
153
153
|
|
154
154
|
####read access
|
155
155
|
o=Order.load_from_file("order.xml")
|
156
|
-
=> #<Order:
|
156
|
+
=> #<Order:0x00007fa316170280 @signatures=[#<Signature:0x00007fa316153c98 @position="product manager", @name="John Doe">, #<Signature:0x00007fa316152320 @position="clerk", @name="Jill Smith">, #<Signature:0x00007fa31614b890 @position="Some Employee", @name="Miles O'Brien">], @reference="12343-AHSHE-314159", @client=#<Client:0x00007fa31616afb0 @work_address=#<Address:0x00007fa316168210 @city="San Francisco", @state="CA", @zip=94102, @street="98765, Fulton Street">, @name="Jean Smith", @home_address=#<Address:0x00007fa316169d18 @city="San Mateo", @state="CA", @zip=94403, @street="2000, Alameda de las Pulgas">>, @items={"RF-0001"=>#<Item:0x00007fa316160f60 @descr="Stuffed Penguin", @quantity=10, @unit_price=8.95>, "RF-0034"=>#<Item:0x00007fa31615b920 @descr="Chocolate", @quantity=5, @unit_price=28.5>, "RF-3341"=>#<Item:0x00007fa31615a2a0 @descr="Cookie", @quantity=30, @unit_price=0.85>}>
|
157
157
|
o.reference
|
158
158
|
=> "12343-AHSHE-314159"
|
159
159
|
o.client
|
160
|
-
=> #<Client:
|
160
|
+
=> #<Client:0x00007fa31616afb0 @work_address=#<Address:0x00007fa316168210 @city="San Francisco", @state="CA", @zip=94102, @street="98765, Fulton Street">, @name="Jean Smith", @home_address=#<Address:0x00007fa316169d18 @city="San Mateo", @state="CA", @zip=94403, @street="2000, Alameda de las Pulgas">>
|
161
161
|
o.items.keys
|
162
162
|
=> ["RF-0001", "RF-0034", "RF-3341"]
|
163
163
|
o.items["RF-0034"].descr
|
@@ -165,7 +165,7 @@ http://www.castor.org/xml-mapping.html)
|
|
165
165
|
o.items["RF-0034"].total_price
|
166
166
|
=> 142.5
|
167
167
|
o.signatures
|
168
|
-
=> [#<Signature:
|
168
|
+
=> [#<Signature:0x00007fa316153c98 @position="product manager", @name="John Doe">, #<Signature:0x00007fa316152320 @position="clerk", @name="Jill Smith">, #<Signature:0x00007fa31614b890 @position="Some Employee", @name="Miles O'Brien">]
|
169
169
|
o.signatures[2].name
|
170
170
|
=> "Miles O'Brien"
|
171
171
|
o.signatures[2].position
|
@@ -303,17 +303,17 @@ http://www.castor.org/xml-mapping.html)
|
|
303
303
|
|
304
304
|
####Starting a new order from scratch
|
305
305
|
o = Order.new
|
306
|
-
=> #<Order:
|
306
|
+
=> #<Order:0x00007fa3160c9f48 @signatures=[]>
|
307
307
|
## attributes with default values (here: signatures) are set
|
308
308
|
## automatically
|
309
309
|
|
310
310
|
xml=o.save_to_xml
|
311
311
|
XML::MappingError: no value, and no default value, for attribute: reference
|
312
|
-
from /
|
313
|
-
from /
|
314
|
-
from /
|
315
|
-
from /
|
316
|
-
from /
|
312
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:724:in `obj_to_xml'
|
313
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:218:in `block in fill_into_xml'
|
314
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:217:in `each'
|
315
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:217:in `fill_into_xml'
|
316
|
+
from /Users/oklischat/xml-mapping/lib/xml/mapping/base.rb:229:in `save_to_xml'
|
317
317
|
## can't save as long as there are still unset attributes without
|
318
318
|
## default values
|
319
319
|
|
@@ -568,7 +568,7 @@ document like this one:
|
|
568
568
|
usage:
|
569
569
|
|
570
570
|
ppl=People.load_from_file("stringarray.xml")
|
571
|
-
=> #<People:
|
571
|
+
=> #<People:0x00007fa316332050 @names=["Jim", "Susan", "Herbie", "Nancy"]>
|
572
572
|
ppl.names
|
573
573
|
=> ["Jim", "Susan", "Herbie", "Nancy"]
|
574
574
|
|
@@ -675,11 +675,11 @@ Usage:
|
|
675
675
|
|
676
676
|
|
677
677
|
root = XML::Mapping.load_object_from_file "documents_folders.xml"
|
678
|
-
=> #<Folder:
|
678
|
+
=> #<Folder:0x00007fa3162cadd8 @entries=[#<Document:0x00007fa3162ca018 @name="plan", @contents=" inhale, exhale">, #<Folder:0x00007fa3162c9410 @entries=[#<Folder:0x00007fa3162c8768 @entries=[#<Document:0x00007fa316132318 @name="README", @contents="foo bar baz">], @name="xml-mapping">], @name="work">], @name="home">
|
679
679
|
root.name
|
680
680
|
=> "home"
|
681
681
|
root.entries
|
682
|
-
=> [#<Document:
|
682
|
+
=> [#<Document:0x00007fa3162ca018 @name="plan", @contents=" inhale, exhale">, #<Folder:0x00007fa3162c9410 @entries=[#<Folder:0x00007fa3162c8768 @entries=[#<Document:0x00007fa316132318 @name="README", @contents="foo bar baz">], @name="xml-mapping">], @name="work">]
|
683
683
|
|
684
684
|
root.append "etc", Folder.new
|
685
685
|
root["etc"].append "passwd", Document.new
|
@@ -933,22 +933,22 @@ declarations that declare XML mappings for the day, month etc. fields:
|
|
933
933
|
nowxml.write($stdout,2)
|
934
934
|
<time>
|
935
935
|
<year>
|
936
|
-
|
936
|
+
2017
|
937
937
|
</year>
|
938
938
|
<month>
|
939
|
-
|
939
|
+
12
|
940
940
|
</month>
|
941
941
|
<mday>
|
942
|
-
|
942
|
+
29
|
943
943
|
</mday>
|
944
944
|
<hours>
|
945
|
-
|
945
|
+
16
|
946
946
|
</hours>
|
947
947
|
<minutes>
|
948
|
-
|
948
|
+
9
|
949
949
|
</minutes>
|
950
950
|
<seconds>
|
951
|
-
|
951
|
+
59
|
952
952
|
</seconds>
|
953
953
|
</time>
|
954
954
|
|
@@ -1031,7 +1031,7 @@ attribute) or several "contributors" (contained in a sequence of
|
|
1031
1031
|
### usage
|
1032
1032
|
|
1033
1033
|
p1 = Publication.load_from_xml(REXML::Document.new('<publication author="Jim"/>').root)
|
1034
|
-
=> #<Publication:
|
1034
|
+
=> #<Publication:0x00007fa3178fb940 @author="Jim">
|
1035
1035
|
|
1036
1036
|
p2 = Publication.load_from_xml(REXML::Document.new('
|
1037
1037
|
<publication>
|
@@ -1039,7 +1039,7 @@ attribute) or several "contributors" (contained in a sequence of
|
|
1039
1039
|
<contr>Mel</contr>
|
1040
1040
|
<contr>Toby</contr>
|
1041
1041
|
</publication>').root)
|
1042
|
-
=> #<Publication:
|
1042
|
+
=> #<Publication:0x00007fa317902420 @contributors=["Chris", "Mel", "Toby"]>
|
1043
1043
|
|
1044
1044
|
The symbols :if, :then, and :elsif (but not :else -- see below) in the
|
1045
1045
|
+choice_node+'s node factory method call are ignored; they may be
|
@@ -1093,13 +1093,13 @@ itself. You can achieve this with +choice_node+ like this:
|
|
1093
1093
|
### usage
|
1094
1094
|
|
1095
1095
|
p1 = Person.load_from_xml(REXML::Document.new('<person name="Jim"/>').root)
|
1096
|
-
=> #<Person:
|
1096
|
+
=> #<Person:0x00007fa31704d3e8 @name="Jim">
|
1097
1097
|
|
1098
1098
|
p2 = Person.load_from_xml(REXML::Document.new('<person><name>James</name></person>').root)
|
1099
|
-
=> #<Person:
|
1099
|
+
=> #<Person:0x00007fa31700ead0 @name="James">
|
1100
1100
|
|
1101
1101
|
p3 = Person.load_from_xml(REXML::Document.new('<person>Suzy</person>').root)
|
1102
|
-
=> #<Person:
|
1102
|
+
=> #<Person:0x00007fa3170042d8 @name="Suzy">
|
1103
1103
|
|
1104
1104
|
|
1105
1105
|
p1.save_to_xml.write($stdout)
|
@@ -1147,7 +1147,7 @@ Here's a (really contrived) example:
|
|
1147
1147
|
end
|
1148
1148
|
|
1149
1149
|
f = Foo.load_from_xml(REXML::Document.new('<foo name="Jim" more="XYZ"/>').root)
|
1150
|
-
=> #<Foo:
|
1150
|
+
=> #<Foo:0x00007fa31723eaa8 @name="JimXYZ">
|
1151
1151
|
|
1152
1152
|
xml = f.save_to_xml
|
1153
1153
|
xml.write $stdout,2
|
@@ -1309,7 +1309,7 @@ age and an address:
|
|
1309
1309
|
|
1310
1310
|
## load using the default mapping
|
1311
1311
|
p = Person.load_from_xml xml
|
1312
|
-
=> #<Person:
|
1312
|
+
=> #<Person:0x00007fa31788b7d0 @name="Suzy", @age=28, @address=#<Address:0x00007fa31788ac68 @street="Abbey Road", @number=72, @city="London", @zip=18827>>
|
1313
1313
|
|
1314
1314
|
## save using the default mapping
|
1315
1315
|
xml2 = p.save_to_xml
|
@@ -1352,7 +1352,7 @@ age and an address:
|
|
1352
1352
|
</individual>
|
1353
1353
|
## load it again using the :other mapping
|
1354
1354
|
p2 = Person.load_from_xml other_xml, :mapping=>:other
|
1355
|
-
=> #<Person:
|
1355
|
+
=> #<Person:0x00007fa3178ba8a0 @name="Suzy", @age=28, @address=#<Address:0x00007fa3178b9ce8 @street="Abbey Road", @number=72, @city="London", @zip=18827>>
|
1356
1356
|
|
1357
1357
|
## p2 identical to p
|
1358
1358
|
|
data/user_manual_xxpath.md
CHANGED
@@ -141,7 +141,7 @@ updated in-place.
|
|
141
141
|
## "first" raises XML::XXPathError in such cases...
|
142
142
|
path2.first(d)
|
143
143
|
XML::XXPathError: path not found: /foo/bar[2]/baz[4]
|
144
|
-
from /
|
144
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:75:in `first'
|
145
145
|
|
146
146
|
##...unless we allow nil returns
|
147
147
|
path2.first(d,:allow_nil=>true)
|
@@ -343,7 +343,7 @@ Examples:
|
|
343
343
|
</foo>### no change
|
344
344
|
|
345
345
|
XML::XXPath.new("/bar/baz[6]/@haha").first(rootelt,:ensure_created=>true)
|
346
|
-
=> #<XML::XXPath::Accessors::Attribute:
|
346
|
+
=> #<XML::XXPath::Accessors::Attribute:0x00007fa317891770 @parent=<baz haha='[unset]'/>, @name="haha">
|
347
347
|
d.write($stdout,2)
|
348
348
|
|
349
349
|
<foo>
|
@@ -362,7 +362,7 @@ Examples:
|
|
362
362
|
</foo>### for there to be a 6th "baz" element, there must be 1st..5th "baz" elements
|
363
363
|
|
364
364
|
XML::XXPath.new("/bar/baz[6]/@haha").first(rootelt,:ensure_created=>true)
|
365
|
-
=> #<XML::XXPath::Accessors::Attribute:
|
365
|
+
=> #<XML::XXPath::Accessors::Attribute:0x00007fa316308660 @parent=<baz haha='[unset]'/>, @name="haha">
|
366
366
|
d.write($stdout,2)
|
367
367
|
|
368
368
|
<foo>
|
@@ -456,7 +456,7 @@ Examples:
|
|
456
456
|
path2=XML::XXPath.new("@key2")
|
457
457
|
|
458
458
|
path2.create_new(firstbazelt)
|
459
|
-
=> #<XML::XXPath::Accessors::Attribute:
|
459
|
+
=> #<XML::XXPath::Accessors::Attribute:0x00007fa316862138 @parent=<baz key='work' key2='[unset]'> ... </>, @name="key2">
|
460
460
|
d.write($stdout,2)
|
461
461
|
|
462
462
|
<foo>
|
@@ -479,12 +479,11 @@ Examples:
|
|
479
479
|
### same call again...
|
480
480
|
path2.create_new(firstbazelt)
|
481
481
|
XML::XXPathError: XPath (@key2): create_new and attribute already exists
|
482
|
-
from /
|
483
|
-
from /
|
484
|
-
from /
|
485
|
-
from /
|
486
|
-
from /
|
487
|
-
from /home/olaf/xml-mapping/lib/xml/xxpath.rb:112:in `create_new'
|
482
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath/steps.rb:215:in `create_on'
|
483
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath/steps.rb:80:in `block in creator'
|
484
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:91:in `all'
|
485
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:70:in `first'
|
486
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:112:in `create_new'
|
488
487
|
### can't create that path anew again -- an element can't have more
|
489
488
|
### than one attribute with the same name
|
490
489
|
|
@@ -542,12 +541,11 @@ Examples:
|
|
542
541
|
|
543
542
|
XML::XXPath.new("baz[6]").create_new(baz6elt.parent)
|
544
543
|
XML::XXPathError: XPath: baz[6]: create_new and element already exists
|
545
|
-
from /
|
546
|
-
from /
|
547
|
-
from /
|
548
|
-
from /
|
549
|
-
from /
|
550
|
-
from /home/olaf/xml-mapping/lib/xml/xxpath.rb:112:in `create_new'
|
544
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath/steps.rb:167:in `create_on'
|
545
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath/steps.rb:80:in `block in creator'
|
546
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:91:in `all'
|
547
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:70:in `first'
|
548
|
+
from /Users/oklischat/xml-mapping/lib/xml/xxpath.rb:112:in `create_new'
|
551
549
|
### yep, baz[6] already existed and thus couldn't be created once
|
552
550
|
### again
|
553
551
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xml-mapping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Olaf Klischat
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -92,10 +92,12 @@ files:
|
|
92
92
|
- test/fixtures/company1.xml
|
93
93
|
- test/fixtures/documents_folders.xml
|
94
94
|
- test/fixtures/documents_folders2.xml
|
95
|
+
- test/fixtures/number.xml
|
95
96
|
- test/fixtures/triangle_m1.xml
|
96
97
|
- test/fixtures/triangle_m2.xml
|
97
98
|
- test/inheritance_test.rb
|
98
99
|
- test/multiple_mappings_test.rb
|
100
|
+
- test/number.rb
|
99
101
|
- test/rexml_xpath_benchmark.rb
|
100
102
|
- test/tests_init.rb
|
101
103
|
- test/triangle_mm.rb
|
@@ -128,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
130
|
version: '0'
|
129
131
|
requirements: []
|
130
132
|
rubyforge_project: xml-mapping
|
131
|
-
rubygems_version: 2.
|
133
|
+
rubygems_version: 2.7.3
|
132
134
|
signing_key:
|
133
135
|
specification_version: 4
|
134
136
|
summary: XML-Object mapper for Ruby
|