xml-mapping 0.8.1 → 0.9.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.
Files changed (71) hide show
  1. data/ChangeLog +64 -3
  2. data/README +871 -173
  3. data/README_XPATH +40 -13
  4. data/Rakefile +37 -26
  5. data/TODO.txt +39 -8
  6. data/examples/README +5 -0
  7. data/examples/company_usage.intout +34 -22
  8. data/examples/documents_folders.rb +31 -0
  9. data/examples/documents_folders.xml +16 -0
  10. data/examples/documents_folders_usage.intin.rb +18 -0
  11. data/examples/documents_folders_usage.intout +46 -0
  12. data/examples/order_signature_enhanced_usage.intout +21 -11
  13. data/examples/order_usage.intin.rb +52 -5
  14. data/examples/order_usage.intout +154 -80
  15. data/examples/person.intin.rb +44 -0
  16. data/examples/person.intout +27 -0
  17. data/examples/person_mm.intin.rb +119 -0
  18. data/examples/person_mm.intout +114 -0
  19. data/examples/publication.intin.rb +44 -0
  20. data/examples/publication.intout +20 -0
  21. data/examples/reader.intin.rb +33 -0
  22. data/examples/reader.intout +19 -0
  23. data/examples/stringarray.rb +5 -0
  24. data/examples/stringarray.xml +10 -0
  25. data/examples/stringarray_usage.intin.rb +11 -0
  26. data/examples/stringarray_usage.intout +31 -0
  27. data/examples/time_augm.intout +19 -7
  28. data/examples/time_augm_loading.intin.rb +44 -0
  29. data/examples/time_augm_loading.intout +12 -0
  30. data/examples/time_node.intin.rb +79 -0
  31. data/examples/time_node.rb +3 -2
  32. data/examples/time_node_w_marshallers.intin.rb +48 -0
  33. data/examples/time_node_w_marshallers.intout +25 -0
  34. data/examples/time_node_w_marshallers.xml +9 -0
  35. data/examples/xpath_create_new.intout +132 -114
  36. data/examples/xpath_ensure_created.intout +86 -65
  37. data/examples/xpath_pathological.intout +16 -16
  38. data/examples/xpath_usage.intout +1 -1
  39. data/install.rb +1 -0
  40. data/lib/xml/mapping.rb +3 -1
  41. data/lib/xml/mapping/base.rb +442 -272
  42. data/lib/xml/mapping/core_classes_mapping.rb +32 -0
  43. data/lib/xml/mapping/standard_nodes.rb +176 -86
  44. data/lib/xml/mapping/version.rb +2 -2
  45. data/lib/xml/rexml_ext.rb +186 -0
  46. data/lib/xml/xxpath.rb +28 -265
  47. data/lib/xml/xxpath/steps.rb +345 -0
  48. data/lib/xml/xxpath_methods.rb +96 -0
  49. data/test/all_tests.rb +4 -1
  50. data/test/benchmark_fixtures.rb +14 -0
  51. data/test/{multiple_mappings.rb → bookmarks.rb} +0 -0
  52. data/test/company.rb +47 -0
  53. data/test/documents_folders.rb +11 -1
  54. data/test/examples_test.rb +29 -0
  55. data/test/fixtures/benchmark.xml +77 -0
  56. data/test/fixtures/company1.xml +9 -0
  57. data/test/fixtures/documents_folders.xml +0 -8
  58. data/test/fixtures/documents_folders2.xml +13 -19
  59. data/test/fixtures/triangle_m1.xml +17 -0
  60. data/test/fixtures/triangle_m2.xml +19 -0
  61. data/test/inheritance_test.rb +50 -0
  62. data/test/multiple_mappings_test.rb +155 -0
  63. data/test/rexml_xpath_benchmark.rb +29 -0
  64. data/test/triangle_mm.rb +57 -0
  65. data/test/xml_mapping_adv_test.rb +36 -1
  66. data/test/xml_mapping_test.rb +136 -7
  67. data/test/xpath_test.rb +154 -0
  68. data/test/xxpath_benchmark.rb +36 -0
  69. data/test/xxpath_benchmark.result1.txt +17 -0
  70. data/test/xxpath_methods_test.rb +61 -0
  71. metadata +139 -90
@@ -0,0 +1,46 @@
1
+
2
+ root = XML::Mapping.load_object_from_file "documents_folders.xml"
3
+ => #<Folder:0x7f48766041e8 @name="home", @entries=[#<Document:0x7f4876600f70 @name="plan", @contents=" inhale, exhale">, #<Folder:0x7f48765febf8 @name="work", @entries=[#<Folder:0x7f48765fc1a0 @name="xml-mapping", @entries=[#<Document:0x7f48765fa6c0 @name="README", @contents="foo bar baz">]>]>]>
4
+ root.name
5
+ => "home"
6
+ root.entries
7
+ => [#<Document:0x7f4876600f70 @name="plan", @contents=" inhale, exhale">, #<Folder:0x7f48765febf8 @name="work", @entries=[#<Folder:0x7f48765fc1a0 @name="xml-mapping", @entries=[#<Document:0x7f48765fa6c0 @name="README", @contents="foo bar baz">]>]>]
8
+
9
+ root.append "etc", Folder.new
10
+ root["etc"].append "passwd", Document.new
11
+ root["etc"]["passwd"].contents = "foo:x:2:2:/bin/sh"
12
+ root["etc"].append "hosts", Document.new
13
+ root["etc"]["hosts"].contents = "127.0.0.1 localhost"
14
+
15
+ xml = root.save_to_xml
16
+ => <folder name='home'> ... </>
17
+ xml.write $stdout,2
18
+
19
+ <folder name='home'>
20
+ <document name='plan'>
21
+ <contents>
22
+ inhale, exhale
23
+ </contents>
24
+ </document>
25
+ <folder name='work'>
26
+ <folder name='xml-mapping'>
27
+ <document name='README'>
28
+ <contents>
29
+ foo bar baz
30
+ </contents>
31
+ </document>
32
+ </folder>
33
+ </folder>
34
+ <folder name='etc'>
35
+ <document name='passwd'>
36
+ <contents>
37
+ foo:x:2:2:/bin/sh
38
+ </contents>
39
+ </document>
40
+ <document name='hosts'>
41
+ <contents>
42
+ 127.0.0.1 localhost
43
+ </contents>
44
+ </document>
45
+ </folder>
46
+ </folder>
@@ -1,16 +1,26 @@
1
1
  s=Signature.load_from_file("order_signature_enhanced.xml")
2
- => #<Signature:0x1aed60 @signed_on=Sun Feb 13 00:00:00 MET 2005, @name="John Doe", @position="product manager">
2
+ => #<Signature:0x7f487642e850 @signed_on=Sun Feb 13 00:00:00 +0100 2005, @name="John Doe", @position="product manager">
3
3
  s.signed_on
4
- => Sun Feb 13 00:00:00 MET 2005
4
+ => Sun Feb 13 00:00:00 +0100 2005
5
5
  s.signed_on=Time.local(1976,12,18)
6
- => Sat Dec 18 00:00:00 MET 1976
6
+ => Sat Dec 18 00:00:00 +0100 1976
7
7
  s.save_to_xml.write($stdout,2)
8
8
  <signature>
9
- <Name>John Doe</Name>
10
- <Position>product manager</Position>
11
- <signed-on>
12
- <year>1976</year>
13
- <month>12</month>
14
- <day>18</day>
15
- </signed-on>
16
- </signature>=> #<File:examples/order_signature_enhanced_usage.intout>
9
+ <Name>
10
+ John Doe
11
+ </Name>
12
+ <Position>
13
+ product manager
14
+ </Position>
15
+ <signed-on>
16
+ <year>
17
+ 1976
18
+ </year>
19
+ <month>
20
+ 12
21
+ </month>
22
+ <day>
23
+ 18
24
+ </day>
25
+ </signed-on>
26
+ </signature>=> #<File:examples/order_signature_enhanced_usage.intout>
@@ -4,7 +4,12 @@ begin
4
4
  Object.send(:remove_const, "Address") # name clash with company_usage...
5
5
  rescue
6
6
  end
7
- require 'order' #<=
7
+ require 'order'
8
+
9
+ require 'xml/xxpath_methods'
10
+
11
+ require 'test/unit/assertions'
12
+ include Test::Unit::Assertions #<=
8
13
  #:visible:
9
14
  ####read access
10
15
  o=Order.load_from_file("order.xml") #<=
@@ -20,6 +25,17 @@ o.signatures[2].position #<=
20
25
 
21
26
  o.total_price #<=
22
27
 
28
+ #:invisible:
29
+ assert_equal "12343-AHSHE-314159", o.reference
30
+ assert_equal "Jean Smith", o.client.name
31
+ assert_equal "San Francisco", o.client.work_address.city
32
+ assert_equal "San Mateo", o.client.home_address.city
33
+ assert_equal %w{RF-0001 RF-0034 RF-3341}, o.items.keys.sort
34
+ assert_equal ['John Doe','Jill Smith','Miles O\'Brien'], o.signatures.map{|s|s.name}
35
+ assert_equal 2575, (10 * o.total_price).round
36
+ #<=
37
+ #:visible:
38
+
23
39
  ####write access
24
40
  o.client.name="James T. Kirk"
25
41
  o.items['RF-4711'] = Item.new
@@ -34,8 +50,17 @@ o.signatures << s
34
50
  xml=o.save_to_xml #convert to REXML node; there's also o.save_to_file(name) #<=
35
51
  #:invisible_retval:
36
52
  xml.write($stdout,2) #<=
37
- #:visible_retval:
38
53
 
54
+ #:invisible:
55
+ assert_equal %w{RF-0001 RF-0034 RF-3341 RF-4711}, xml.all_xpath("Item/@reference").map{|x|x.text}.sort
56
+ assert_equal ['John Doe','Jill Smith','Miles O\'Brien','Harry Smith'],
57
+ xml.all_xpath("Signed-By/Signature/Name").map{|x|x.text}
58
+ #<=
59
+ #:visible:
60
+
61
+
62
+ #<=
63
+ #:visible_retval:
39
64
  ####Starting a new order from scratch
40
65
  o = Order.new #<=
41
66
  ## attributes with default values (here: signatures) are set
@@ -63,11 +88,33 @@ o.items['XY-42'].quantity = 3
63
88
  o.items['XY-42'].unit_price = 299.95
64
89
 
65
90
  #:invisible_retval:
66
- o.save_to_xml.write($stdout,2)
91
+ xml=o.save_to_xml
92
+ xml.write($stdout,2)
67
93
  #<=
68
- #:visible_retval:
94
+ #:invisible:
95
+ assert_equal "order", xml.name
96
+ assert_equal o.reference, xml.first_xpath("@reference").text
97
+ assert_equal o.client.name, xml.first_xpath("Client/Name").text
98
+ assert_equal o.client.home_address.street, xml.first_xpath("Client/Address[@where='home']/Street").text
99
+ assert_equal o.client.home_address.city, xml.first_xpath("Client/Address[@where='home']/City").text
100
+ assert_nil xml.first_xpath("Client/Address[@where='work']", :allow_nil=>true)
101
+ assert_equal 1, xml.all_xpath("Client/Address").size
102
+
103
+ o.client.work_address = Address.new
104
+ o.client.work_address.street = 'milky way 2'
105
+ o.client.work_address.city = 'Ursa Major'
106
+ o.client.work_address.zip = 18293
107
+ o.client.work_address.state = 'Magellan Cloud'
108
+ xml=o.save_to_xml
109
+
110
+ assert_equal o.client.work_address.street, xml.first_xpath("Client/Address[@where='work']/Street").text
111
+ assert_equal o.client.work_address.city, xml.first_xpath("Client/Address[@where='work']/City").text
112
+ assert_equal o.client.home_address.street, xml.first_xpath("Client/Address[@where='home']/Street").text
113
+ assert_equal 2, xml.all_xpath("Client/Address").size
114
+ #<=
115
+ #:visible:
69
116
 
70
117
  ## the root element name when saving an object to XML will by default
71
118
  ## be derived from the class name (in this example, "Order" became
72
119
  ## "order"). This can be overridden on a per-class basis; see
73
- ## XML::Mapping::ClassMethods#root_element_namefor details.
120
+ ## XML::Mapping::ClassMethods#root_element_name for details.
@@ -1,10 +1,10 @@
1
1
  ####read access
2
2
  o=Order.load_from_file("order.xml")
3
- => #<Order:0x404730 @items={"RF-3341"=>#<Item:0x3f7fb0 @unit_price=0.85, @quantity=30, @descr="Cookie">, "RF-0034"=>#<Item:0x3faa70 @unit_price=28.5, @quantity=5, @descr="Chocolate">, "RF-0001"=>#<Item:0x3fcfa8 @unit_price=8.95, @quantity=10, @descr="Stuffed Penguin">}, @signatures=[#<Signature:0x3f4878 @name="John Doe", @position="product manager">, #<Signature:0x3f38d0 @name="Jill Smith", @position="clerk">, #<Signature:0x3f23a0 @name="Miles O'Brien", @position="Some Employee">], @client=#<Client:0x403a70 @work_address=#<Address:0x3ffbb8 @street="98765, Fulton Street", @state="CA", @zip=94102, @city="San Francisco">, @name="Jean Smith", @home_address=#<Address:0x402450 @street="2000, Alameda de las Pulgas", @state="CA", @zip=94403, @city="San Mateo">>, @reference="12343-AHSHE-314159">
3
+ => #<Order:0x7f4877650510 @reference="12343-AHSHE-314159", @signatures=[#<Signature:0x7f48776282b8 @name="John Doe", @position="product manager">, #<Signature:0x7f4877626d28 @name="Jill Smith", @position="clerk">, #<Signature:0x7f4877625798 @name="Miles O'Brien", @position="Some Employee">], @items={"RF-3341"=>#<Item:0x7f487762d290 @quantity=30, @descr="Cookie", @unit_price=0.85>, "RF-0034"=>#<Item:0x7f4877632808 @quantity=5, @descr="Chocolate", @unit_price=28.5>, "RF-0001"=>#<Item:0x7f487763a558 @quantity=10, @descr="Stuffed Penguin", @unit_price=8.95>}, @client=#<Client:0x7f487764d9c8 @name="Jean Smith", @work_address=#<Address:0x7f4877641588 @zip=94102, @street="98765, Fulton Street", @city="San Francisco", @state="CA">, @home_address=#<Address:0x7f4877645d40 @zip=94403, @street="2000, Alameda de las Pulgas", @city="San Mateo", @state="CA">>>
4
4
  o.reference
5
5
  => "12343-AHSHE-314159"
6
6
  o.client
7
- => #<Client:0x403a70 @work_address=#<Address:0x3ffbb8 @street="98765, Fulton Street", @state="CA", @zip=94102, @city="San Francisco">, @name="Jean Smith", @home_address=#<Address:0x402450 @street="2000, Alameda de las Pulgas", @state="CA", @zip=94403, @city="San Mateo">>
7
+ => #<Client:0x7f487764d9c8 @name="Jean Smith", @work_address=#<Address:0x7f4877641588 @zip=94102, @street="98765, Fulton Street", @city="San Francisco", @state="CA">, @home_address=#<Address:0x7f4877645d40 @zip=94403, @street="2000, Alameda de las Pulgas", @city="San Mateo", @state="CA">>
8
8
  o.items.keys
9
9
  => ["RF-3341", "RF-0034", "RF-0001"]
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:0x3f4878 @name="John Doe", @position="product manager">, #<Signature:0x3f38d0 @name="Jill Smith", @position="clerk">, #<Signature:0x3f23a0 @name="Miles O'Brien", @position="Some Employee">]
15
+ => [#<Signature:0x7f48776282b8 @name="John Doe", @position="product manager">, #<Signature:0x7f4877626d28 @name="Jill Smith", @position="clerk">, #<Signature:0x7f4877625798 @name="Miles O'Brien", @position="Some Employee">]
16
16
  o.signatures[2].name
17
17
  => "Miles O'Brien"
18
18
  o.signatures[2].position
@@ -37,72 +37,130 @@ xml=o.save_to_xml #convert to REXML node; there's also o.save_to_file(name)
37
37
  => <order reference='12343-AHSHE-314159'> ... </>
38
38
  xml.write($stdout,2)
39
39
  <order reference='12343-AHSHE-314159'>
40
- <Client>
41
- <Name>James T. Kirk</Name>
42
- <Address where='home'>
43
- <City>San Mateo</City>
44
- <State>CA</State>
45
- <ZIP>94403</ZIP>
46
- <Street>2000, Alameda de las Pulgas</Street>
47
- </Address>
48
- <Address where='work'>
49
- <City>San Francisco</City>
50
- <State>CA</State>
51
- <ZIP>94102</ZIP>
52
- <Street>98765, Fulton Street</Street>
53
- </Address>
54
- </Client>
55
- <Item reference='RF-3341'>
56
- <Description>Cookie</Description>
57
- <Quantity>30</Quantity>
58
- <UnitPrice>0.85</UnitPrice>
59
- </Item>
60
- <Item reference='RF-0034'>
61
- <Description>Chocolate</Description>
62
- <Quantity>5</Quantity>
63
- <UnitPrice>28.5</UnitPrice>
64
- </Item>
65
- <Item reference='RF-0001'>
66
- <Description>Stuffed Penguin</Description>
67
- <Quantity>10</Quantity>
68
- <UnitPrice>8.95</UnitPrice>
69
- </Item>
70
- <Item reference='RF-4711'>
71
- <Description>power transfer grid</Description>
72
- <Quantity>2</Quantity>
73
- <UnitPrice>29.95</UnitPrice>
74
- </Item>
75
- <Signed-By>
76
- <Signature>
77
- <Name>John Doe</Name>
78
- <Position>product manager</Position>
79
- </Signature>
80
- <Signature>
81
- <Name>Jill Smith</Name>
82
- <Position>clerk</Position>
83
- </Signature>
84
- <Signature>
85
- <Name>Miles O&apos;Brien</Name>
86
- </Signature>
87
- <Signature>
88
- <Name>Harry Smith</Name>
89
- <Position>general manager</Position>
90
- </Signature>
91
- </Signed-By>
92
- </order>
40
+ <Client>
41
+ <Name>
42
+ James T. Kirk
43
+ </Name>
44
+ <Address where='home'>
45
+ <City>
46
+ San Mateo
47
+ </City>
48
+ <State>
49
+ CA
50
+ </State>
51
+ <ZIP>
52
+ 94403
53
+ </ZIP>
54
+ <Street>
55
+ 2000, Alameda de las Pulgas
56
+ </Street>
57
+ </Address>
58
+ <Address where='work'>
59
+ <City>
60
+ San Francisco
61
+ </City>
62
+ <State>
63
+ CA
64
+ </State>
65
+ <ZIP>
66
+ 94102
67
+ </ZIP>
68
+ <Street>
69
+ 98765, Fulton Street
70
+ </Street>
71
+ </Address>
72
+ </Client>
73
+ <Item reference='RF-3341'>
74
+ <Description>
75
+ Cookie
76
+ </Description>
77
+ <Quantity>
78
+ 30
79
+ </Quantity>
80
+ <UnitPrice>
81
+ 0.85
82
+ </UnitPrice>
83
+ </Item>
84
+ <Item reference='RF-4711'>
85
+ <Description>
86
+ power transfer grid
87
+ </Description>
88
+ <Quantity>
89
+ 2
90
+ </Quantity>
91
+ <UnitPrice>
92
+ 29.95
93
+ </UnitPrice>
94
+ </Item>
95
+ <Item reference='RF-0034'>
96
+ <Description>
97
+ Chocolate
98
+ </Description>
99
+ <Quantity>
100
+ 5
101
+ </Quantity>
102
+ <UnitPrice>
103
+ 28.5
104
+ </UnitPrice>
105
+ </Item>
106
+ <Item reference='RF-0001'>
107
+ <Description>
108
+ Stuffed Penguin
109
+ </Description>
110
+ <Quantity>
111
+ 10
112
+ </Quantity>
113
+ <UnitPrice>
114
+ 8.95
115
+ </UnitPrice>
116
+ </Item>
117
+ <Signed-By>
118
+ <Signature>
119
+ <Name>
120
+ John Doe
121
+ </Name>
122
+ <Position>
123
+ product manager
124
+ </Position>
125
+ </Signature>
126
+ <Signature>
127
+ <Name>
128
+ Jill Smith
129
+ </Name>
130
+ <Position>
131
+ clerk
132
+ </Position>
133
+ </Signature>
134
+ <Signature>
135
+ <Name>
136
+ Miles O&apos;Brien
137
+ </Name>
138
+ </Signature>
139
+ <Signature>
140
+ <Name>
141
+ Harry Smith
142
+ </Name>
143
+ <Position>
144
+ general manager
145
+ </Position>
146
+ </Signature>
147
+ </Signed-By>
148
+ </order>
149
+
150
+
93
151
  ####Starting a new order from scratch
94
152
  o = Order.new
95
- => #<Order:0x3b5500 @signatures=[]>
153
+ => #<Order:0x7f48766fc118 @signatures=[]>
96
154
  ## attributes with default values (here: signatures) are set
97
155
  ## automatically
98
156
 
99
157
  xml=o.save_to_xml
100
158
  XML::MappingError: no value, and no default value, for attribute: reference
101
- from ../lib/xml/../xml/mapping/base.rb:381:in `obj_to_xml'
102
- from ../lib/xml/../xml/mapping/base.rb:157:in `fill_into_xml'
103
- from ../lib/xml/../xml/mapping/base.rb:156:in `each'
104
- from ../lib/xml/../xml/mapping/base.rb:156:in `fill_into_xml'
105
- from ../lib/xml/../xml/mapping/base.rb:168:in `save_to_xml'
159
+ from ../lib/xml/../xml/mapping/base.rb:697:in `obj_to_xml'
160
+ from ../lib/xml/../xml/mapping/base.rb:218:in `fill_into_xml'
161
+ from ../lib/xml/../xml/mapping/base.rb:217:in `each'
162
+ from ../lib/xml/../xml/mapping/base.rb:217:in `fill_into_xml'
163
+ from ../lib/xml/../xml/mapping/base.rb:229:in `save_to_xml'
106
164
  ## can't save as long as there are still unset attributes without
107
165
  ## default values
108
166
 
@@ -121,27 +179,43 @@ o.items['XY-42'].descr = 'improbability drive'
121
179
  o.items['XY-42'].quantity = 3
122
180
  o.items['XY-42'].unit_price = 299.95
123
181
 
124
- o.save_to_xml.write($stdout,2)
182
+ xml=o.save_to_xml
183
+ xml.write($stdout,2)
125
184
 
126
185
  <order reference='FOOBAR-1234'>
127
- <Client>
128
- <Name>Ford Prefect</Name>
129
- <Address where='home'>
130
- <City>small planet</City>
131
- <State>Betelgeuse system</State>
132
- <ZIP>17263</ZIP>
133
- <Street>42 Park Av.</Street>
134
- </Address>
135
- </Client>
136
- <Item reference='XY-42'>
137
- <Description>improbability drive</Description>
138
- <Quantity>3</Quantity>
139
- <UnitPrice>299.95</UnitPrice>
140
- </Item>
141
- </order>
186
+ <Client>
187
+ <Name>
188
+ Ford Prefect
189
+ </Name>
190
+ <Address where='home'>
191
+ <City>
192
+ small planet
193
+ </City>
194
+ <State>
195
+ Betelgeuse system
196
+ </State>
197
+ <ZIP>
198
+ 17263
199
+ </ZIP>
200
+ <Street>
201
+ 42 Park Av.
202
+ </Street>
203
+ </Address>
204
+ </Client>
205
+ <Item reference='XY-42'>
206
+ <Description>
207
+ improbability drive
208
+ </Description>
209
+ <Quantity>
210
+ 3
211
+ </Quantity>
212
+ <UnitPrice>
213
+ 299.95
214
+ </UnitPrice>
215
+ </Item>
216
+ </order>
142
217
  ## the root element name when saving an object to XML will by default
143
218
  ## be derived from the class name (in this example, "Order" became
144
219
  ## "order"). This can be overridden on a per-class basis; see
145
- ## XML::Mapping::ClassMethods#root_element_namefor details.
220
+ ## XML::Mapping::ClassMethods#root_element_name for details.
146
221
 
147
- => nil
@@ -0,0 +1,44 @@
1
+ #:invisible:
2
+ $:.unshift "../lib"
3
+ require 'xml/mapping'
4
+ require 'xml/xxpath_methods'
5
+ #<=
6
+ #:visible:
7
+
8
+ class Person
9
+ include XML::Mapping
10
+
11
+ choice_node :if, 'name', :then, (text_node :name, 'name'),
12
+ :elsif, '@name', :then, (text_node :name, '@name'),
13
+ :else, (text_node :name, '.')
14
+ end
15
+
16
+ ### usage
17
+
18
+ p1 = Person.load_from_xml(REXML::Document.new('<person name="Jim"/>').root)#<=
19
+
20
+ p2 = Person.load_from_xml(REXML::Document.new('<person><name>James</name></person>').root)#<=
21
+
22
+ p3 = Person.load_from_xml(REXML::Document.new('<person>Suzy</person>').root)#<=
23
+
24
+
25
+ #:invisible_retval:
26
+ p1.save_to_xml.write($stdout)#<=
27
+
28
+ p2.save_to_xml.write($stdout)#<=
29
+
30
+ p3.save_to_xml.write($stdout)#<=
31
+
32
+ #:invisible:
33
+ require 'test/unit/assertions'
34
+ include Test::Unit::Assertions
35
+
36
+ assert_equal "Jim", p1.name
37
+ assert_equal "James", p2.name
38
+ assert_equal "Suzy", p3.name
39
+
40
+ xml = p3.save_to_xml
41
+ assert_equal "name", xml.elements[1].name
42
+ assert_equal "Suzy", xml.elements[1].text
43
+
44
+ #<=