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
data/test/all_tests.rb
ADDED
data/test/company.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'xml/mapping'
|
2
|
+
|
3
|
+
# forward declarations
|
4
|
+
class Address; end
|
5
|
+
class Office; end
|
6
|
+
class Customer; end
|
7
|
+
|
8
|
+
|
9
|
+
class Company
|
10
|
+
include XML::Mapping
|
11
|
+
|
12
|
+
text_node :name, "@name"
|
13
|
+
|
14
|
+
object_node :address, "address", :class=>Address
|
15
|
+
|
16
|
+
array_node :offices, "offices", "office", :class=>Office
|
17
|
+
hash_node :customers, "customers", "customer", "@uid", :class=>Customer
|
18
|
+
|
19
|
+
text_node :ent1, "arrtest/entry[1]"
|
20
|
+
text_node :ent2, "arrtest/entry[2]"
|
21
|
+
text_node :ent3, "arrtest/entry[3]"
|
22
|
+
|
23
|
+
array_node :stuff, "stuff", "*"
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
class Address
|
28
|
+
include XML::Mapping
|
29
|
+
|
30
|
+
text_node :city, "city"
|
31
|
+
numeric_node :zip, "zip", :default_value=>12576
|
32
|
+
text_node :street, "street", :optional=>true
|
33
|
+
numeric_node :number, "number"
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
class Office
|
38
|
+
include XML::Mapping
|
39
|
+
|
40
|
+
text_node :speciality, "@speciality"
|
41
|
+
boolean_node :classified, "classified", "yes", "no"
|
42
|
+
# object_node :address, "address", :class=>Address
|
43
|
+
object_node :address, "address",
|
44
|
+
:marshaller=>proc {|xml,value| value.fill_into_xml(xml)},
|
45
|
+
:unmarshaller=>proc {|xml| Address.load_from_xml(xml)}
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
class Customer
|
50
|
+
include XML::Mapping
|
51
|
+
|
52
|
+
text_node :uid, "@uid"
|
53
|
+
text_node :name, "name"
|
54
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'xml/mapping'
|
2
|
+
|
3
|
+
class Entry
|
4
|
+
include XML::Mapping
|
5
|
+
|
6
|
+
text_node :name, "name"
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
class Document <Entry
|
11
|
+
include XML::Mapping
|
12
|
+
|
13
|
+
text_node :contents, "contents"
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
Document===other and
|
17
|
+
other.name==self.name and
|
18
|
+
other.contents==self.contents
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
class Folder <Entry
|
24
|
+
include XML::Mapping
|
25
|
+
|
26
|
+
array_node :entries, "entries", "*"
|
27
|
+
|
28
|
+
def ==(other)
|
29
|
+
Folder===other and
|
30
|
+
other.name==self.name and
|
31
|
+
other.entries==self.entries
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
<folder1 name="root" last-changed="123">
|
4
|
+
<entries1>
|
5
|
+
<bookmark1 bmname="ruby" bmlast-changed="345">
|
6
|
+
<url>http://www.ruby-lang.org</url>
|
7
|
+
</bookmark1>
|
8
|
+
|
9
|
+
<bookmark1 bmname="RAA">
|
10
|
+
<url>http://raa.ruby-lang.org/</url>
|
11
|
+
</bookmark1>
|
12
|
+
|
13
|
+
<folder1 name="news">
|
14
|
+
<entries1>
|
15
|
+
<bookmark1 bmname="/." bmlast-changed="233">
|
16
|
+
<url>http://www.slashdot.org/</url>
|
17
|
+
</bookmark1>
|
18
|
+
<bookmark1 bmname="groklaw" bmlast-changed="238">
|
19
|
+
<url>http://www.groklaw.net/</url>
|
20
|
+
</bookmark1>
|
21
|
+
</entries1>
|
22
|
+
</folder1>
|
23
|
+
</entries1>
|
24
|
+
</folder1>
|
@@ -0,0 +1,85 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
<company name="ACME inc.">
|
4
|
+
|
5
|
+
<address>
|
6
|
+
<city>Berlin</city>
|
7
|
+
<zip>10176</zip>
|
8
|
+
<street>Unter den Linden</street>
|
9
|
+
<number>12</number>
|
10
|
+
</address>
|
11
|
+
|
12
|
+
<offices>
|
13
|
+
<office speciality="pencils">
|
14
|
+
<classified>no</classified>
|
15
|
+
<address>
|
16
|
+
<city>Hamburg</city>
|
17
|
+
<zip>18282</zip>
|
18
|
+
<street>Feldweg</street>
|
19
|
+
<number>28</number>
|
20
|
+
</address>
|
21
|
+
</office>
|
22
|
+
<office speciality="weapons of mass destruction">
|
23
|
+
<classified>yes</classified>
|
24
|
+
<address>
|
25
|
+
<city>Baghdad</city>
|
26
|
+
<street>Airport</street>
|
27
|
+
<number>18</number>
|
28
|
+
</address>
|
29
|
+
</office>
|
30
|
+
</offices>
|
31
|
+
|
32
|
+
|
33
|
+
<customers>
|
34
|
+
|
35
|
+
<customer uid="jim">
|
36
|
+
<name>James Kirk</name>
|
37
|
+
<payment_method>cash</payment_method>
|
38
|
+
</customer>
|
39
|
+
|
40
|
+
<customer uid="ernie">
|
41
|
+
<name>Ernie</name>
|
42
|
+
<payment_method>sweeties</payment_method>
|
43
|
+
</customer>
|
44
|
+
|
45
|
+
<customer uid="cm">
|
46
|
+
<name>Cookie Monster</name>
|
47
|
+
<payment_method>cookies</payment_method>
|
48
|
+
</customer>
|
49
|
+
|
50
|
+
<customer uid="sad">
|
51
|
+
<name>Saddam Hussein</name>
|
52
|
+
<payment_method>independent arms broker</payment_method>
|
53
|
+
</customer>
|
54
|
+
|
55
|
+
</customers>
|
56
|
+
|
57
|
+
|
58
|
+
<arrtest>
|
59
|
+
<entry>foo</entry>
|
60
|
+
<entry>bar</entry>
|
61
|
+
<entry>baz</entry>
|
62
|
+
</arrtest>
|
63
|
+
|
64
|
+
|
65
|
+
<stuff>
|
66
|
+
<customer uid="sad">
|
67
|
+
<name>Saddam Hussein</name>
|
68
|
+
<payment_method>independent arms broker</payment_method>
|
69
|
+
</customer>
|
70
|
+
<address>
|
71
|
+
<city>Berlin</city>
|
72
|
+
<zip>10176</zip>
|
73
|
+
<street>Unter den Linden</street>
|
74
|
+
<number>12</number>
|
75
|
+
</address>
|
76
|
+
<office speciality="weapons of mass destruction">
|
77
|
+
<classified>yes</classified>
|
78
|
+
<address>
|
79
|
+
<city>Baghdad</city>
|
80
|
+
<street>Airport</street>
|
81
|
+
<number>18</number>
|
82
|
+
</address>
|
83
|
+
</office>
|
84
|
+
</stuff>
|
85
|
+
</company>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
|
4
|
+
<folder>
|
5
|
+
<name>home</name>
|
6
|
+
|
7
|
+
<entries>
|
8
|
+
<document>
|
9
|
+
<name>plan</name>
|
10
|
+
<contents>
|
11
|
+
inhale, exhale
|
12
|
+
eat, drink, sleep
|
13
|
+
</contents>
|
14
|
+
</document>
|
15
|
+
|
16
|
+
<folder>
|
17
|
+
<name>work</name>
|
18
|
+
|
19
|
+
<entries>
|
20
|
+
<folder>
|
21
|
+
<name>xml-mapping</name>
|
22
|
+
|
23
|
+
<entries>
|
24
|
+
<document>
|
25
|
+
<name>README</name>
|
26
|
+
<contents>
|
27
|
+
XML-MAPPING: XML-to-object (and back) mapper
|
28
|
+
for Ruby, including XPath interpreter
|
29
|
+
</contents>
|
30
|
+
</document>
|
31
|
+
<document>
|
32
|
+
<name>Rakefile</name>
|
33
|
+
<contents>
|
34
|
+
rake away
|
35
|
+
</contents>
|
36
|
+
</document>
|
37
|
+
</entries>
|
38
|
+
</folder>
|
39
|
+
|
40
|
+
<document>
|
41
|
+
<name>schedule</name>
|
42
|
+
<contents>
|
43
|
+
12:00 AM lunch
|
44
|
+
4:00 PM appointment
|
45
|
+
</contents>
|
46
|
+
</document>
|
47
|
+
</entries>
|
48
|
+
</folder>
|
49
|
+
|
50
|
+
|
51
|
+
<folder>
|
52
|
+
<name>books</name>
|
53
|
+
|
54
|
+
<entries>
|
55
|
+
<document>
|
56
|
+
<name>The Hitchhiker's Guide to the Galaxy</name>
|
57
|
+
<contents>
|
58
|
+
The Answer to Life, the Universe, and Everything
|
59
|
+
</contents>
|
60
|
+
</document>
|
61
|
+
<document>
|
62
|
+
<name>Programming Ruby</name>
|
63
|
+
<contents>
|
64
|
+
The Pragmatic Programmer's Guide
|
65
|
+
</contents>
|
66
|
+
</document>
|
67
|
+
</entries>
|
68
|
+
</folder>
|
69
|
+
|
70
|
+
</entries>
|
71
|
+
</folder>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
<folder>
|
4
|
+
<name>home</name>
|
5
|
+
|
6
|
+
<entries>
|
7
|
+
<document>
|
8
|
+
<name>plan</name>
|
9
|
+
<contents> inhale, exhale</contents>
|
10
|
+
</document>
|
11
|
+
|
12
|
+
<folder>
|
13
|
+
<name>work</name>
|
14
|
+
|
15
|
+
<entries>
|
16
|
+
<folder>
|
17
|
+
<name>xml-mapping</name>
|
18
|
+
|
19
|
+
<entries>
|
20
|
+
<document>
|
21
|
+
<name>README</name>
|
22
|
+
<contents>foo bar baz</contents>
|
23
|
+
</document>
|
24
|
+
</entries>
|
25
|
+
</folder>
|
26
|
+
</entries>
|
27
|
+
</folder>
|
28
|
+
|
29
|
+
</entries>
|
30
|
+
</folder>
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class BMNode
|
2
|
+
attr_accessor :name
|
3
|
+
|
4
|
+
def name=(x)
|
5
|
+
@name_set="#{x}_set"
|
6
|
+
@name=x
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
@name_get="#{@name}_get"
|
11
|
+
@name
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :name_set, :name_get
|
15
|
+
|
16
|
+
attr_accessor :last_changed
|
17
|
+
|
18
|
+
def ==(other)
|
19
|
+
other.name==self.name and
|
20
|
+
other.last_changed==self.last_changed
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
yield(self) if block_given?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class BMFolder < BMNode
|
29
|
+
attr_accessor :entries
|
30
|
+
|
31
|
+
def ==(other)
|
32
|
+
super(other) and
|
33
|
+
self.entries == other.entries
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class BM < BMNode
|
38
|
+
attr_accessor :url
|
39
|
+
attr_accessor :refinement
|
40
|
+
|
41
|
+
def ==(other)
|
42
|
+
super(other) and
|
43
|
+
self.url == other.url and
|
44
|
+
self.refinement == other.refinement
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
require 'xml/mapping'
|
51
|
+
|
52
|
+
module Mapping1
|
53
|
+
class BMFolderMapping < BMFolder
|
54
|
+
include XML::Mapping
|
55
|
+
|
56
|
+
root_element_name 'folder1'
|
57
|
+
|
58
|
+
text_node :name, "@name"
|
59
|
+
numeric_node :last_changed, "@last-changed", :default_value=>nil
|
60
|
+
|
61
|
+
array_node :entries, "entries1", "*"
|
62
|
+
end
|
63
|
+
|
64
|
+
class BMMapping < BM
|
65
|
+
include XML::Mapping
|
66
|
+
|
67
|
+
root_element_name 'bookmark1'
|
68
|
+
|
69
|
+
text_node :name, "@bmname"
|
70
|
+
numeric_node :last_changed, "@bmlast-changed", :default_value=>nil
|
71
|
+
|
72
|
+
text_node :url, "url"
|
73
|
+
object_node :refinement, "refinement", :default_value=>nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
module Mapping2
|
79
|
+
# TODO
|
80
|
+
end
|
data/test/tests_init.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.dirname(__FILE__)+"/tests_init"
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'documents_folders'
|
5
|
+
require 'multiple_mappings'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
class XmlMappingAdvancedTest < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@f_xml = REXML::Document.new(File.new(File.dirname(__FILE__) + "/fixtures/documents_folders2.xml"))
|
11
|
+
@f = XML::Mapping.load_object_from_xml(@f_xml.root)
|
12
|
+
|
13
|
+
@bm1_xml = REXML::Document.new(File.new(File.dirname(__FILE__) + "/fixtures/bookmarks1.xml"))
|
14
|
+
@bm1 = XML::Mapping.load_object_from_xml(@bm1_xml.root)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_read_polymorphic_object
|
18
|
+
assert_equal YAML::load(<<-EOS), @f
|
19
|
+
--- !ruby/object:Folder
|
20
|
+
entries:
|
21
|
+
- !ruby/object:Document
|
22
|
+
contents: " inhale, exhale"
|
23
|
+
name: plan
|
24
|
+
- !ruby/object:Folder
|
25
|
+
entries:
|
26
|
+
- !ruby/object:Folder
|
27
|
+
entries:
|
28
|
+
- !ruby/object:Document
|
29
|
+
contents: foo bar baz
|
30
|
+
name: README
|
31
|
+
name: xml-mapping
|
32
|
+
name: work
|
33
|
+
name: home
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def test_read_bookmars1_2
|
39
|
+
expected = BMFolder.new{|x|
|
40
|
+
x.name = "root"
|
41
|
+
x.last_changed = 123
|
42
|
+
x.entries = [
|
43
|
+
BM.new{|x|
|
44
|
+
x.name="ruby"
|
45
|
+
x.last_changed=345
|
46
|
+
x.url="http://www.ruby-lang.org"
|
47
|
+
x.refinement=nil
|
48
|
+
},
|
49
|
+
BM.new{|x|
|
50
|
+
x.name="RAA"
|
51
|
+
x.last_changed=nil
|
52
|
+
x.url="http://raa.ruby-lang.org/"
|
53
|
+
x.refinement=nil
|
54
|
+
},
|
55
|
+
BMFolder.new{|x|
|
56
|
+
x.name="news"
|
57
|
+
x.last_changed=nil
|
58
|
+
x.entries = [
|
59
|
+
BM.new{|x|
|
60
|
+
x.name="/."
|
61
|
+
x.last_changed=233
|
62
|
+
x.url="http://www.slashdot.org/"
|
63
|
+
x.refinement=nil
|
64
|
+
},
|
65
|
+
BM.new{|x|
|
66
|
+
x.name="groklaw"
|
67
|
+
x.last_changed=238
|
68
|
+
x.url="http://www.groklaw.net/"
|
69
|
+
x.refinement=nil
|
70
|
+
}
|
71
|
+
]
|
72
|
+
}
|
73
|
+
]
|
74
|
+
}
|
75
|
+
# need to compare expected==@bm1 because @bm1.== would be the
|
76
|
+
# XML::Mapping#== defined in xml_mapping_test.rb ...
|
77
|
+
assert_equal expected, @bm1
|
78
|
+
assert_equal "root_set", @bm1.name_set
|
79
|
+
assert_equal "ruby_set", @bm1.entries[0].name_set
|
80
|
+
@bm1.entries[0].name = "foobar"
|
81
|
+
assert_equal "foobar_set", @bm1.entries[0].name_set
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|