xml-mapping 0.8
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.
- 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,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
|