xml-mapping 0.8.1 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ #<=