xml-mapping 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/LICENSE +56 -0
  2. data/README +386 -0
  3. data/README_XPATH +175 -0
  4. data/Rakefile +214 -0
  5. data/TODO.txt +32 -0
  6. data/doc/xpath_impl_notes.txt +119 -0
  7. data/examples/company.rb +34 -0
  8. data/examples/company.xml +26 -0
  9. data/examples/company_usage.intin.rb +19 -0
  10. data/examples/company_usage.intout +39 -0
  11. data/examples/order.rb +61 -0
  12. data/examples/order.xml +54 -0
  13. data/examples/order_signature_enhanced.rb +7 -0
  14. data/examples/order_signature_enhanced.xml +9 -0
  15. data/examples/order_signature_enhanced_usage.intin.rb +12 -0
  16. data/examples/order_signature_enhanced_usage.intout +16 -0
  17. data/examples/order_usage.intin.rb +73 -0
  18. data/examples/order_usage.intout +147 -0
  19. data/examples/time_augm.intin.rb +19 -0
  20. data/examples/time_augm.intout +23 -0
  21. data/examples/time_node.rb +27 -0
  22. data/examples/xpath_create_new.intin.rb +85 -0
  23. data/examples/xpath_create_new.intout +181 -0
  24. data/examples/xpath_docvsroot.intin.rb +30 -0
  25. data/examples/xpath_docvsroot.intout +34 -0
  26. data/examples/xpath_ensure_created.intin.rb +62 -0
  27. data/examples/xpath_ensure_created.intout +114 -0
  28. data/examples/xpath_pathological.intin.rb +42 -0
  29. data/examples/xpath_pathological.intout +56 -0
  30. data/examples/xpath_usage.intin.rb +51 -0
  31. data/examples/xpath_usage.intout +57 -0
  32. data/install.rb +40 -0
  33. data/lib/xml/mapping.rb +14 -0
  34. data/lib/xml/mapping/base.rb +563 -0
  35. data/lib/xml/mapping/standard_nodes.rb +343 -0
  36. data/lib/xml/mapping/version.rb +8 -0
  37. data/lib/xml/xxpath.rb +354 -0
  38. data/test/all_tests.rb +6 -0
  39. data/test/company.rb +54 -0
  40. data/test/documents_folders.rb +33 -0
  41. data/test/fixtures/bookmarks1.xml +24 -0
  42. data/test/fixtures/company1.xml +85 -0
  43. data/test/fixtures/documents_folders.xml +71 -0
  44. data/test/fixtures/documents_folders2.xml +30 -0
  45. data/test/multiple_mappings.rb +80 -0
  46. data/test/tests_init.rb +2 -0
  47. data/test/xml_mapping_adv_test.rb +84 -0
  48. data/test/xml_mapping_test.rb +182 -0
  49. data/test/xpath_test.rb +273 -0
  50. metadata +96 -0
@@ -0,0 +1,23 @@
1
+ class Time
2
+ include XML::Mapping
3
+
4
+ numeric_node :year, "year"
5
+ numeric_node :month, "month"
6
+ numeric_node :day, "mday"
7
+ numeric_node :hour, "hours"
8
+ numeric_node :min, "minutes"
9
+ numeric_node :sec, "seconds"
10
+ end
11
+
12
+
13
+ nowxml=Time.now.save_to_xml
14
+ => <time> ... </>
15
+ nowxml.write($stdout,2)
16
+ <time>
17
+ <year>2005</year>
18
+ <month>7</month>
19
+ <mday>7</mday>
20
+ <hours>6</hours>
21
+ <minutes>10</minutes>
22
+ <seconds>49</seconds>
23
+ </time>
@@ -0,0 +1,27 @@
1
+ require 'xml/mapping/base'
2
+
3
+ class TimeNode < XML::Mapping::SingleAttributeNode
4
+ def initialize_impl(path)
5
+ @y_path = XML::XXPath.new(path+"/year")
6
+ @m_path = XML::XXPath.new(path+"/month")
7
+ @d_path = XML::XXPath.new(path+"/day")
8
+ end
9
+
10
+ def extract_attr_value(xml)
11
+ y,m,d = default_when_xpath_err{ [@y_path.first(xml).text.to_i,
12
+ @m_path.first(xml).text.to_i,
13
+ @d_path.first(xml).text.to_i]
14
+ }
15
+ Time.local(y,m,d)
16
+ end
17
+
18
+ def set_attr_value(xml, value)
19
+ raise "Not a Time: #{value}" unless Time===value
20
+ @y_path.first(xml,:ensure_created=>true).text = value.year
21
+ @m_path.first(xml,:ensure_created=>true).text = value.month
22
+ @d_path.first(xml,:ensure_created=>true).text = value.day
23
+ end
24
+ end
25
+
26
+
27
+ XML::Mapping.add_node_class TimeNode
@@ -0,0 +1,85 @@
1
+ #:invisible:
2
+ $:.unshift "../lib" #<=
3
+ #:visible:
4
+ require 'xml/xxpath'
5
+
6
+ d=REXML::Document.new <<EOS
7
+ <foo>
8
+ <bar>
9
+ <baz key="work">Java</baz>
10
+ <baz key="play">Ruby</baz>
11
+ </bar>
12
+ </foo>
13
+ EOS
14
+
15
+
16
+ rootelt=d.root
17
+
18
+ #:invisible_retval:
19
+ path1=XML::XXPath.new("/bar/baz[@key='work']")
20
+
21
+ #:visible_retval:
22
+ path1.create_new(rootelt)#<=
23
+ #:invisible_retval:
24
+ d.write($stdout,2)#<=
25
+ ### a new element is created for *each* path element, regardless of
26
+ ### what existed before. So a new "bar" element was added, with a new
27
+ ### "baz" element inside it
28
+
29
+ ### same call again...
30
+ #:visible_retval:
31
+ path1.create_new(rootelt)#<=
32
+ #:invisible_retval:
33
+ d.write($stdout,2)#<=
34
+ ### same procedure -- new elements added for each path element
35
+
36
+
37
+ #:visible_retval:
38
+ ## get reference to 1st "baz" element
39
+ firstbazelt=XML::XXPath.new("/bar/baz").first(rootelt)#<=
40
+
41
+ #:invisible_retval:
42
+ path2=XML::XXPath.new("@key2")
43
+
44
+ #:visible_retval:
45
+ path2.create_new(firstbazelt)#<=
46
+ #:invisible_retval:
47
+ d.write($stdout,2)#<=
48
+ ### ok, new attribute node added
49
+
50
+ ### same call again...
51
+ #:visible_retval:
52
+ #:handle_exceptions:
53
+ path2.create_new(firstbazelt)#<=
54
+ #:no_exceptions:
55
+ ### can't create that path anew again -- an element can't have more
56
+ ### than one attribute with the same name
57
+
58
+ #:invisible_retval:
59
+ ### the document hasn't changed
60
+ d.write($stdout,2)#<=
61
+
62
+
63
+
64
+ ### create_new the same path as in the ensure_created example
65
+ #:visible_retval:
66
+ baz6elt=XML::XXPath.new("/bar/baz[6]").create_new(rootelt)#<=
67
+ #:invisible_retval:
68
+ d.write($stdout,2)#<=
69
+ ### ok, new "bar" element and 6th "baz" element inside it created
70
+
71
+
72
+ #:visible_retval:
73
+ #:handle_exceptions:
74
+ XML::XXPath.new("baz[6]").create_new(baz6elt.parent)#<=
75
+ #:no_exceptions:
76
+ #:invisible_retval:
77
+ ### yep, baz[6] already existed and thus couldn't be created once
78
+ ### again
79
+
80
+ ### but of course...
81
+ #:visible_retval:
82
+ XML::XXPath.new("/bar/baz[6]").create_new(rootelt)#<=
83
+ #:invisible_retval:
84
+ d.write($stdout,2)#<=
85
+ ### this works because *all* path elements are newly created
@@ -0,0 +1,181 @@
1
+ require 'xml/xxpath'
2
+
3
+ d=REXML::Document.new <<EOS
4
+ <foo>
5
+ <bar>
6
+ <baz key="work">Java</baz>
7
+ <baz key="play">Ruby</baz>
8
+ </bar>
9
+ </foo>
10
+ EOS
11
+
12
+
13
+ rootelt=d.root
14
+
15
+ path1=XML::XXPath.new("/bar/baz[@key='work']")
16
+
17
+ path1.create_new(rootelt)
18
+ => <baz key='work'/>
19
+ d.write($stdout,2)
20
+ <foo>
21
+ <bar>
22
+ <baz key='work'>Java</baz>
23
+ <baz key='play'>Ruby</baz>
24
+ </bar>
25
+ <bar>
26
+ <baz key='work'/>
27
+ </bar>
28
+ </foo>
29
+
30
+ ### a new element is created for *each* path element, regardless of
31
+ ### what existed before. So a new "bar" element was added, with a new
32
+ ### "baz" element inside it
33
+
34
+ ### same call again...
35
+ path1.create_new(rootelt)
36
+ => <baz key='work'/>
37
+ d.write($stdout,2)
38
+ <foo>
39
+ <bar>
40
+ <baz key='work'>Java</baz>
41
+ <baz key='play'>Ruby</baz>
42
+ </bar>
43
+ <bar>
44
+ <baz key='work'/>
45
+ </bar>
46
+ <bar>
47
+ <baz key='work'/>
48
+ </bar>
49
+ </foo>
50
+
51
+ ### same procedure -- new elements added for each path element
52
+
53
+
54
+ ## get reference to 1st "baz" element
55
+ firstbazelt=XML::XXPath.new("/bar/baz").first(rootelt)
56
+ => <baz key='work'> ... </>
57
+
58
+ path2=XML::XXPath.new("@key2")
59
+
60
+ path2.create_new(firstbazelt)
61
+ => #<XML::XXPath::Accessors::Attribute:0x404b0c4c @name="key2", @parent=<baz key2='[unset]' key='work'> ... </>>
62
+ d.write($stdout,2)
63
+ <foo>
64
+ <bar>
65
+ <baz key2='[unset]' key='work'>Java</baz>
66
+ <baz key='play'>Ruby</baz>
67
+ </bar>
68
+ <bar>
69
+ <baz key='work'/>
70
+ </bar>
71
+ <bar>
72
+ <baz key='work'/>
73
+ </bar>
74
+ </foo>
75
+
76
+ ### ok, new attribute node added
77
+
78
+ ### same call again...
79
+ path2.create_new(firstbazelt)
80
+ XML::XXPathError: XPath (): @key2: create_new and attribute already exists
81
+ from ../lib/xml/../xml/xxpath.rb:341:in `create_subnode_by_attr_name'
82
+ from ../lib/xml/../xml/xxpath.rb:68:in `initialize'
83
+ from ../lib/xml/../xml/xxpath.rb:67:in `call'
84
+ from ../lib/xml/../xml/xxpath.rb:146:in `all'
85
+ from ../lib/xml/../xml/xxpath.rb:125:in `first'
86
+ from ../lib/xml/../xml/xxpath.rb:167:in `create_new'
87
+ ### can't create that path anew again -- an element can't have more
88
+ ### than one attribute with the same name
89
+
90
+ ### the document hasn't changed
91
+ d.write($stdout,2)
92
+ <foo>
93
+ <bar>
94
+ <baz key2='[unset]' key='work'>Java</baz>
95
+ <baz key='play'>Ruby</baz>
96
+ </bar>
97
+ <bar>
98
+ <baz key='work'/>
99
+ </bar>
100
+ <bar>
101
+ <baz key='work'/>
102
+ </bar>
103
+ </foo>
104
+
105
+
106
+
107
+
108
+ ### create_new the same path as in the ensure_created example
109
+ baz6elt=XML::XXPath.new("/bar/baz[6]").create_new(rootelt)
110
+ => <baz/>
111
+ d.write($stdout,2)
112
+ <foo>
113
+ <bar>
114
+ <baz key2='[unset]' key='work'>Java</baz>
115
+ <baz key='play'>Ruby</baz>
116
+ </bar>
117
+ <bar>
118
+ <baz key='work'/>
119
+ </bar>
120
+ <bar>
121
+ <baz key='work'/>
122
+ </bar>
123
+ <bar>
124
+ <baz/>
125
+ <baz/>
126
+ <baz/>
127
+ <baz/>
128
+ <baz/>
129
+ <baz/>
130
+ </bar>
131
+ </foo>
132
+
133
+ ### ok, new "bar" element and 6th "baz" element inside it created
134
+
135
+
136
+ XML::XXPath.new("baz[6]").create_new(baz6elt.parent)
137
+ XML::XXPathError: XPath (): baz[6]: create_new and element already exists
138
+ from ../lib/xml/../xml/xxpath.rb:330:in `create_subnode_by_name_and_index'
139
+ from ../lib/xml/../xml/xxpath.rb:52:in `initialize'
140
+ from ../lib/xml/../xml/xxpath.rb:51:in `call'
141
+ from ../lib/xml/../xml/xxpath.rb:146:in `all'
142
+ from ../lib/xml/../xml/xxpath.rb:125:in `first'
143
+ from ../lib/xml/../xml/xxpath.rb:167:in `create_new'
144
+ ### yep, baz[6] already existed and thus couldn't be created once
145
+ ### again
146
+
147
+ ### but of course...
148
+ XML::XXPath.new("/bar/baz[6]").create_new(rootelt)
149
+ => <baz/>
150
+ d.write($stdout,2)
151
+ <foo>
152
+ <bar>
153
+ <baz key2='[unset]' key='work'>Java</baz>
154
+ <baz key='play'>Ruby</baz>
155
+ </bar>
156
+ <bar>
157
+ <baz key='work'/>
158
+ </bar>
159
+ <bar>
160
+ <baz key='work'/>
161
+ </bar>
162
+ <bar>
163
+ <baz/>
164
+ <baz/>
165
+ <baz/>
166
+ <baz/>
167
+ <baz/>
168
+ <baz/>
169
+ </bar>
170
+ <bar>
171
+ <baz/>
172
+ <baz/>
173
+ <baz/>
174
+ <baz/>
175
+ <baz/>
176
+ <baz/>
177
+ </bar>
178
+ </foo>
179
+
180
+ ### this works because *all* path elements are newly created
181
+
@@ -0,0 +1,30 @@
1
+ #:invisible:
2
+ $:.unshift "../lib" #<=
3
+ #:visible:
4
+ require 'xml/xxpath'
5
+
6
+ d=REXML::Document.new <<EOS
7
+ <foo>
8
+ <bar x="hello">
9
+ <first>
10
+ <second>pingpong</second>
11
+ </first>
12
+ </bar>
13
+ <bar x="goodbye"/>
14
+ </foo>
15
+ EOS
16
+
17
+ XML::XXPath.new("/foo/bar").all(d)#<=
18
+
19
+ XML::XXPath.new("/bar").all(d)#<=
20
+
21
+ XML::XXPath.new("/foo/bar").all(d.root)#<=
22
+
23
+ XML::XXPath.new("/bar").all(d.root)#<=
24
+
25
+
26
+ firstelt = XML::XXPath.new("/foo/bar/first").first(d)#<=
27
+
28
+ XML::XXPath.new("/first/second").all(firstelt)#<=
29
+
30
+ XML::XXPath.new("/second").all(firstelt)#<=
@@ -0,0 +1,34 @@
1
+ require 'xml/xxpath'
2
+
3
+ d=REXML::Document.new <<EOS
4
+ <foo>
5
+ <bar x="hello">
6
+ <first>
7
+ <second>pingpong</second>
8
+ </first>
9
+ </bar>
10
+ <bar x="goodbye"/>
11
+ </foo>
12
+ EOS
13
+
14
+ XML::XXPath.new("/foo/bar").all(d)
15
+ => [<bar x='hello'> ... </>, <bar x='goodbye'/>]
16
+
17
+ XML::XXPath.new("/bar").all(d)
18
+ => []
19
+
20
+ XML::XXPath.new("/foo/bar").all(d.root)
21
+ => []
22
+
23
+ XML::XXPath.new("/bar").all(d.root)
24
+ => [<bar x='hello'> ... </>, <bar x='goodbye'/>]
25
+
26
+
27
+ firstelt = XML::XXPath.new("/foo/bar/first").first(d)
28
+ => <first> ... </>
29
+
30
+ XML::XXPath.new("/first/second").all(firstelt)
31
+ => []
32
+
33
+ XML::XXPath.new("/second").all(firstelt)
34
+ => [<second> ... </>]
@@ -0,0 +1,62 @@
1
+ #:invisible:
2
+ $:.unshift "../lib" #<=
3
+ #:visible:
4
+ require 'xml/xxpath'
5
+
6
+ d=REXML::Document.new <<EOS
7
+ <foo>
8
+ <bar>
9
+ <baz key="work">Java</baz>
10
+ <baz key="play">Ruby</baz>
11
+ </bar>
12
+ </foo>
13
+ EOS
14
+
15
+
16
+ rootelt=d.root
17
+
18
+ #### ensuring that a specific path exists inside the document
19
+
20
+ #:visible_retval:
21
+ XML::XXPath.new("/bar/baz[@key='work']").first(rootelt,:ensure_created=>true)#<=
22
+ #:invisible_retval:
23
+ d.write($stdout,2)#<=
24
+ ### no change (path existed before)
25
+
26
+
27
+ #:visible_retval:
28
+ XML::XXPath.new("/bar/baz[@key='42']").first(rootelt,:ensure_created=>true)#<=
29
+ #:invisible_retval:
30
+ d.write($stdout,2)#<=
31
+ ### path was added
32
+
33
+ #:visible_retval:
34
+ XML::XXPath.new("/bar/baz[@key='42']").first(rootelt,:ensure_created=>true)#<=
35
+ #:invisible_retval:
36
+ d.write($stdout,2)#<=
37
+ ### no change this time
38
+
39
+ #:visible_retval:
40
+ XML::XXPath.new("/bar/baz[@key2='hello']").first(rootelt,:ensure_created=>true)#<=
41
+ #:invisible_retval:
42
+ d.write($stdout,2)#<=
43
+ ### this fit in the 1st "baz" element since
44
+ ### there was no "key2" attribute there before.
45
+
46
+ #:visible_retval:
47
+ XML::XXPath.new("/bar/baz[2]").first(rootelt,:ensure_created=>true)#<=
48
+ #:invisible_retval:
49
+ d.write($stdout,2)#<=
50
+ ### no change
51
+
52
+ #:visible_retval:
53
+ XML::XXPath.new("/bar/baz[6]/@haha").first(rootelt,:ensure_created=>true)#<=
54
+ #:invisible_retval:
55
+ d.write($stdout,2)#<=
56
+ ### for there to be a 6th "baz" element, there must be 1st..5th "baz" elements
57
+
58
+ #:visible_retval:
59
+ XML::XXPath.new("/bar/baz[6]/@haha").first(rootelt,:ensure_created=>true)#<=
60
+ #:invisible_retval:
61
+ d.write($stdout,2)#<=
62
+ ### no change this time