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