xml-mapping 0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +56 -0
- data/README +386 -0
- data/README_XPATH +175 -0
- data/Rakefile +214 -0
- data/TODO.txt +32 -0
- data/doc/xpath_impl_notes.txt +119 -0
- data/examples/company.rb +34 -0
- data/examples/company.xml +26 -0
- data/examples/company_usage.intin.rb +19 -0
- data/examples/company_usage.intout +39 -0
- data/examples/order.rb +61 -0
- data/examples/order.xml +54 -0
- data/examples/order_signature_enhanced.rb +7 -0
- data/examples/order_signature_enhanced.xml +9 -0
- data/examples/order_signature_enhanced_usage.intin.rb +12 -0
- data/examples/order_signature_enhanced_usage.intout +16 -0
- data/examples/order_usage.intin.rb +73 -0
- data/examples/order_usage.intout +147 -0
- data/examples/time_augm.intin.rb +19 -0
- data/examples/time_augm.intout +23 -0
- data/examples/time_node.rb +27 -0
- data/examples/xpath_create_new.intin.rb +85 -0
- data/examples/xpath_create_new.intout +181 -0
- data/examples/xpath_docvsroot.intin.rb +30 -0
- data/examples/xpath_docvsroot.intout +34 -0
- data/examples/xpath_ensure_created.intin.rb +62 -0
- data/examples/xpath_ensure_created.intout +114 -0
- data/examples/xpath_pathological.intin.rb +42 -0
- data/examples/xpath_pathological.intout +56 -0
- data/examples/xpath_usage.intin.rb +51 -0
- data/examples/xpath_usage.intout +57 -0
- data/install.rb +40 -0
- data/lib/xml/mapping.rb +14 -0
- data/lib/xml/mapping/base.rb +563 -0
- data/lib/xml/mapping/standard_nodes.rb +343 -0
- data/lib/xml/mapping/version.rb +8 -0
- data/lib/xml/xxpath.rb +354 -0
- data/test/all_tests.rb +6 -0
- data/test/company.rb +54 -0
- data/test/documents_folders.rb +33 -0
- data/test/fixtures/bookmarks1.xml +24 -0
- data/test/fixtures/company1.xml +85 -0
- data/test/fixtures/documents_folders.xml +71 -0
- data/test/fixtures/documents_folders2.xml +30 -0
- data/test/multiple_mappings.rb +80 -0
- data/test/tests_init.rb +2 -0
- data/test/xml_mapping_adv_test.rb +84 -0
- data/test/xml_mapping_test.rb +182 -0
- data/test/xpath_test.rb +273 -0
- metadata +96 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
c = Company.load_from_file('company.xml')
|
2
|
+
=> #<Company:0x40471c18 @address=#<Address:0x40471344 @zip=10113, @city="Berlin">, @name="ACME inc.", @customers=[#<Customer:0x4046fe90 @name="James Kirk", @id="jim">, #<Customer:0x4046f51c @name="Ernie", @id="ernie">, #<Customer:0x4046eba8 @name="Bert", @id="bert">]>
|
3
|
+
c.name
|
4
|
+
=> "ACME inc."
|
5
|
+
c.customers.size
|
6
|
+
=> 3
|
7
|
+
c.customers[1]
|
8
|
+
=> #<Customer:0x4046f51c @name="Ernie", @id="ernie">
|
9
|
+
c.customers[1].name
|
10
|
+
=> "Ernie"
|
11
|
+
c.customers[0].name
|
12
|
+
=> "James Kirk"
|
13
|
+
c.customers[0].name = 'James Tiberius Kirk'
|
14
|
+
=> "James Tiberius Kirk"
|
15
|
+
c.customers << Customer.new('cm','Cookie Monster')
|
16
|
+
=> [#<Customer:0x4046fe90 @name="James Tiberius Kirk", @id="jim">, #<Customer:0x4046f51c @name="Ernie", @id="ernie">, #<Customer:0x4046eba8 @name="Bert", @id="bert">, #<Customer:0x4046d7a8 @name="Cookie Monster", @id="cm">]
|
17
|
+
xml2 = c.save_to_xml
|
18
|
+
=> <company name='ACME inc.'> ... </>
|
19
|
+
xml2.write($stdout,2)
|
20
|
+
<company name='ACME inc.'>
|
21
|
+
<address>
|
22
|
+
<city>Berlin</city>
|
23
|
+
<zip>10113</zip>
|
24
|
+
</address>
|
25
|
+
<customers>
|
26
|
+
<customer id='539197256'>
|
27
|
+
<name>James Tiberius Kirk</name>
|
28
|
+
</customer>
|
29
|
+
<customer id='539196046'>
|
30
|
+
<name>Ernie</name>
|
31
|
+
</customer>
|
32
|
+
<customer id='539194836'>
|
33
|
+
<name>Bert</name>
|
34
|
+
</customer>
|
35
|
+
<customer id='539192276'>
|
36
|
+
<name>Cookie Monster</name>
|
37
|
+
</customer>
|
38
|
+
</customers>
|
39
|
+
</company>
|
data/examples/order.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'xml/mapping'
|
2
|
+
|
3
|
+
## forward declarations
|
4
|
+
class Client; end
|
5
|
+
class Address; end
|
6
|
+
class Item; end
|
7
|
+
class Signature; end
|
8
|
+
|
9
|
+
|
10
|
+
class Order
|
11
|
+
include XML::Mapping
|
12
|
+
|
13
|
+
text_node :reference, "@reference"
|
14
|
+
object_node :client, "Client", :class=>Client
|
15
|
+
hash_node :items, "Item", "@reference", :class=>Item
|
16
|
+
array_node :signatures, "Signed-By", "Signature", :class=>Signature, :default_value=>[]
|
17
|
+
|
18
|
+
def total_price
|
19
|
+
items.values.map{|i| i.total_price}.inject(0){|x,y|x+y}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
class Client
|
25
|
+
include XML::Mapping
|
26
|
+
|
27
|
+
text_node :name, "Name"
|
28
|
+
object_node :home_address, "Address[@where='home']", :class=>Address
|
29
|
+
object_node :work_address, "Address[@where='work']", :class=>Address, :default_value=>nil
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
class Address
|
34
|
+
include XML::Mapping
|
35
|
+
|
36
|
+
text_node :city, "City"
|
37
|
+
text_node :state, "State"
|
38
|
+
numeric_node :zip, "ZIP"
|
39
|
+
text_node :street, "Street"
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
class Item
|
44
|
+
include XML::Mapping
|
45
|
+
|
46
|
+
text_node :descr, "Description"
|
47
|
+
numeric_node :quantity, "Quantity"
|
48
|
+
numeric_node :unit_price, "UnitPrice"
|
49
|
+
|
50
|
+
def total_price
|
51
|
+
quantity*unit_price
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
class Signature
|
57
|
+
include XML::Mapping
|
58
|
+
|
59
|
+
text_node :name, "Name"
|
60
|
+
text_node :position, "Position", :default_value=>"Some Employee"
|
61
|
+
end
|
data/examples/order.xml
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
<Order reference="12343-AHSHE-314159">
|
4
|
+
<Client>
|
5
|
+
<Name>Jean Smith</Name>
|
6
|
+
<Address where="home">
|
7
|
+
<City>San Mateo</City>
|
8
|
+
<State>CA</State>
|
9
|
+
<ZIP>94403</ZIP>
|
10
|
+
<Street>2000, Alameda de las Pulgas</Street>
|
11
|
+
</Address>
|
12
|
+
<Address where="work">
|
13
|
+
<City>San Francisco</City>
|
14
|
+
<State>CA</State>
|
15
|
+
<ZIP>94102</ZIP>
|
16
|
+
<Street>98765, Fulton Street</Street>
|
17
|
+
</Address>
|
18
|
+
</Client>
|
19
|
+
|
20
|
+
<Item reference="RF-0001">
|
21
|
+
<Description>Stuffed Penguin</Description>
|
22
|
+
<Quantity>10</Quantity>
|
23
|
+
<UnitPrice>8.95</UnitPrice>
|
24
|
+
</Item>
|
25
|
+
|
26
|
+
<Item reference="RF-0034">
|
27
|
+
<Description>Chocolate</Description>
|
28
|
+
<Quantity>5</Quantity>
|
29
|
+
<UnitPrice>28.50</UnitPrice>
|
30
|
+
</Item>
|
31
|
+
|
32
|
+
<Item reference="RF-3341">
|
33
|
+
<Description>Cookie</Description>
|
34
|
+
<Quantity>30</Quantity>
|
35
|
+
<UnitPrice>0.85</UnitPrice>
|
36
|
+
</Item>
|
37
|
+
|
38
|
+
<Signed-By>
|
39
|
+
<Signature>
|
40
|
+
<Name>John Doe</Name>
|
41
|
+
<Position>product manager</Position>
|
42
|
+
</Signature>
|
43
|
+
|
44
|
+
<Signature>
|
45
|
+
<Name>Jill Smith</Name>
|
46
|
+
<Position>clerk</Position>
|
47
|
+
</Signature>
|
48
|
+
|
49
|
+
<Signature>
|
50
|
+
<Name>Miles O'Brien</Name>
|
51
|
+
</Signature>
|
52
|
+
</Signed-By>
|
53
|
+
|
54
|
+
</Order>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#:invisible:
|
2
|
+
$:.unshift "../lib"
|
3
|
+
require 'xml/mapping'
|
4
|
+
require 'time_node.rb'
|
5
|
+
require 'order'
|
6
|
+
require 'order_signature_enhanced'
|
7
|
+
#<=
|
8
|
+
#:visible:
|
9
|
+
s=Signature.load_from_file("order_signature_enhanced.xml") #<=
|
10
|
+
s.signed_on #<=
|
11
|
+
s.signed_on=Time.local(1976,12,18) #<=
|
12
|
+
s.save_to_xml.write($stdout,2) #<=
|
@@ -0,0 +1,16 @@
|
|
1
|
+
s=Signature.load_from_file("order_signature_enhanced.xml")
|
2
|
+
=> #<Signature:0x40476344 @name="John Doe", @signed_on=Sun Feb 13 00:00:00 CET 2005, @position="product manager">
|
3
|
+
s.signed_on
|
4
|
+
=> Sun Feb 13 00:00:00 CET 2005
|
5
|
+
s.signed_on=Time.local(1976,12,18)
|
6
|
+
=> Sat Dec 18 00:00:00 CET 1976
|
7
|
+
s.save_to_xml.write($stdout,2)
|
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>
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#:invisible:
|
2
|
+
$:.unshift "../lib"
|
3
|
+
begin
|
4
|
+
Object.send(:remove_const, "Address") # name clash with company_usage...
|
5
|
+
rescue
|
6
|
+
end
|
7
|
+
require 'order' #<=
|
8
|
+
#:visible:
|
9
|
+
####read access
|
10
|
+
o=Order.load_from_file("order.xml") #<=
|
11
|
+
o.reference #<=
|
12
|
+
o.client #<=
|
13
|
+
o.items.keys #<=
|
14
|
+
o.items["RF-0034"].descr #<=
|
15
|
+
o.items["RF-0034"].total_price #<=
|
16
|
+
o.signatures #<=
|
17
|
+
o.signatures[2].name #<=
|
18
|
+
o.signatures[2].position #<=
|
19
|
+
## default value was set
|
20
|
+
|
21
|
+
o.total_price #<=
|
22
|
+
|
23
|
+
####write access
|
24
|
+
o.client.name="James T. Kirk"
|
25
|
+
o.items['RF-4711'] = Item.new
|
26
|
+
o.items['RF-4711'].descr = 'power transfer grid'
|
27
|
+
o.items['RF-4711'].quantity = 2
|
28
|
+
o.items['RF-4711'].unit_price = 29.95
|
29
|
+
|
30
|
+
s=Signature.new
|
31
|
+
s.name='Harry Smith'
|
32
|
+
s.position='general manager'
|
33
|
+
o.signatures << s
|
34
|
+
xml=o.save_to_xml #convert to REXML node; there's also o.save_to_file(name) #<=
|
35
|
+
#:invisible_retval:
|
36
|
+
xml.write($stdout,2) #<=
|
37
|
+
#:visible_retval:
|
38
|
+
|
39
|
+
####Starting a new order from scratch
|
40
|
+
o = Order.new #<=
|
41
|
+
## attributes with default values (here: signatures) are set
|
42
|
+
## automatically
|
43
|
+
|
44
|
+
#:handle_exceptions:
|
45
|
+
xml=o.save_to_xml #<=
|
46
|
+
#:no_exceptions:
|
47
|
+
## can't save as long as there are still unset attributes without
|
48
|
+
## default values
|
49
|
+
|
50
|
+
o.reference = "FOOBAR-1234"
|
51
|
+
|
52
|
+
o.client = Client.new
|
53
|
+
o.client.name = 'Ford Prefect'
|
54
|
+
o.client.home_address = Address.new
|
55
|
+
o.client.home_address.street = '42 Park Av.'
|
56
|
+
o.client.home_address.city = 'small planet'
|
57
|
+
o.client.home_address.zip = 17263
|
58
|
+
o.client.home_address.state = 'Betelgeuse system'
|
59
|
+
|
60
|
+
o.items={'XY-42' => Item.new}
|
61
|
+
o.items['XY-42'].descr = 'improbability drive'
|
62
|
+
o.items['XY-42'].quantity = 3
|
63
|
+
o.items['XY-42'].unit_price = 299.95
|
64
|
+
|
65
|
+
#:invisible_retval:
|
66
|
+
o.save_to_xml.write($stdout,2)
|
67
|
+
#<=
|
68
|
+
#:visible_retval:
|
69
|
+
|
70
|
+
## the root element name when saving an object to XML will by default
|
71
|
+
## be derived from the class name (in this example, "Order" became
|
72
|
+
## "order"). This can be overridden on a per-class basis; see
|
73
|
+
## XML::Mapping::ClassMethods#root_element_namefor details.
|
@@ -0,0 +1,147 @@
|
|
1
|
+
####read access
|
2
|
+
o=Order.load_from_file("order.xml")
|
3
|
+
=> #<Order:0x40441590 @signatures=[#<Signature:0x40436fc8 @name="John Doe", @position="product manager">, #<Signature:0x404363ac @name="Jill Smith", @position="clerk">, #<Signature:0x40435790 @name="Miles O'Brien", @position="Some Employee">], @items={"RF-3341"=>#<Item:0x40438f58 @unit_price=0.85, @quantity=30, @descr="Cookie">, "RF-0034"=>#<Item:0x4043a7a4 @unit_price=28.5, @quantity=5, @descr="Chocolate">, "RF-0001"=>#<Item:0x4043bff0 @unit_price=8.95, @quantity=10, @descr="Stuffed Penguin">}, @client=#<Client:0x40440be0 @name="Jean Smith", @work_address=#<Address:0x4043e05c @street="98765, Fulton Street", @zip=94102, @state="CA", @city="San Francisco">, @home_address=#<Address:0x4043ff10 @street="2000, Alameda de las Pulgas", @zip=94403, @state="CA", @city="San Mateo">>, @reference="12343-AHSHE-314159">
|
4
|
+
o.reference
|
5
|
+
=> "12343-AHSHE-314159"
|
6
|
+
o.client
|
7
|
+
=> #<Client:0x40440be0 @name="Jean Smith", @work_address=#<Address:0x4043e05c @street="98765, Fulton Street", @zip=94102, @state="CA", @city="San Francisco">, @home_address=#<Address:0x4043ff10 @street="2000, Alameda de las Pulgas", @zip=94403, @state="CA", @city="San Mateo">>
|
8
|
+
o.items.keys
|
9
|
+
=> ["RF-3341", "RF-0034", "RF-0001"]
|
10
|
+
o.items["RF-0034"].descr
|
11
|
+
=> "Chocolate"
|
12
|
+
o.items["RF-0034"].total_price
|
13
|
+
=> 142.5
|
14
|
+
o.signatures
|
15
|
+
=> [#<Signature:0x40436fc8 @name="John Doe", @position="product manager">, #<Signature:0x404363ac @name="Jill Smith", @position="clerk">, #<Signature:0x40435790 @name="Miles O'Brien", @position="Some Employee">]
|
16
|
+
o.signatures[2].name
|
17
|
+
=> "Miles O'Brien"
|
18
|
+
o.signatures[2].position
|
19
|
+
=> "Some Employee"
|
20
|
+
## default value was set
|
21
|
+
|
22
|
+
o.total_price
|
23
|
+
=> 257.5
|
24
|
+
|
25
|
+
####write access
|
26
|
+
o.client.name="James T. Kirk"
|
27
|
+
o.items['RF-4711'] = Item.new
|
28
|
+
o.items['RF-4711'].descr = 'power transfer grid'
|
29
|
+
o.items['RF-4711'].quantity = 2
|
30
|
+
o.items['RF-4711'].unit_price = 29.95
|
31
|
+
|
32
|
+
s=Signature.new
|
33
|
+
s.name='Harry Smith'
|
34
|
+
s.position='general manager'
|
35
|
+
o.signatures << s
|
36
|
+
xml=o.save_to_xml #convert to REXML node; there's also o.save_to_file(name)
|
37
|
+
=> <order reference='12343-AHSHE-314159'> ... </>
|
38
|
+
xml.write($stdout,2)
|
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'Brien</Name>
|
86
|
+
</Signature>
|
87
|
+
<Signature>
|
88
|
+
<Name>Harry Smith</Name>
|
89
|
+
<Position>general manager</Position>
|
90
|
+
</Signature>
|
91
|
+
</Signed-By>
|
92
|
+
</order>
|
93
|
+
####Starting a new order from scratch
|
94
|
+
o = Order.new
|
95
|
+
=> #<Order:0x4053a014 @signatures=[]>
|
96
|
+
## attributes with default values (here: signatures) are set
|
97
|
+
## automatically
|
98
|
+
|
99
|
+
xml=o.save_to_xml
|
100
|
+
XML::MappingError: no value, and no default value, for attribute: reference
|
101
|
+
from ../lib/xml/../xml/mapping/base.rb:377: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'
|
106
|
+
## can't save as long as there are still unset attributes without
|
107
|
+
## default values
|
108
|
+
|
109
|
+
o.reference = "FOOBAR-1234"
|
110
|
+
|
111
|
+
o.client = Client.new
|
112
|
+
o.client.name = 'Ford Prefect'
|
113
|
+
o.client.home_address = Address.new
|
114
|
+
o.client.home_address.street = '42 Park Av.'
|
115
|
+
o.client.home_address.city = 'small planet'
|
116
|
+
o.client.home_address.zip = 17263
|
117
|
+
o.client.home_address.state = 'Betelgeuse system'
|
118
|
+
|
119
|
+
o.items={'XY-42' => Item.new}
|
120
|
+
o.items['XY-42'].descr = 'improbability drive'
|
121
|
+
o.items['XY-42'].quantity = 3
|
122
|
+
o.items['XY-42'].unit_price = 299.95
|
123
|
+
|
124
|
+
o.save_to_xml.write($stdout,2)
|
125
|
+
|
126
|
+
<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>
|
142
|
+
## the root element name when saving an object to XML will by default
|
143
|
+
## be derived from the class name (in this example, "Order" became
|
144
|
+
## "order"). This can be overridden on a per-class basis; see
|
145
|
+
## XML::Mapping::ClassMethods#root_element_namefor details.
|
146
|
+
|
147
|
+
=> nil
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#:invisible:
|
2
|
+
$:.unshift "../lib"
|
3
|
+
require 'order' #<=
|
4
|
+
#:visible:
|
5
|
+
class Time
|
6
|
+
include XML::Mapping
|
7
|
+
|
8
|
+
numeric_node :year, "year"
|
9
|
+
numeric_node :month, "month"
|
10
|
+
numeric_node :day, "mday"
|
11
|
+
numeric_node :hour, "hours"
|
12
|
+
numeric_node :min, "minutes"
|
13
|
+
numeric_node :sec, "seconds"
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
nowxml=Time.now.save_to_xml #<=
|
18
|
+
#:invisible_retval:
|
19
|
+
nowxml.write($stdout,2)#<=
|