raxb 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/raxb.rb +154 -0
  2. data/tests/test.rb +72 -0
  3. metadata +46 -0
data/lib/raxb.rb ADDED
@@ -0,0 +1,154 @@
1
+ require 'rexml/document'
2
+ require 'rexml/element'
3
+
4
+ module RAXB
5
+
6
+ # This function is used to create a RAXB object from a source doucment (either
7
+ # REXML::Document, or anything accepted by the REXML::Document constructor).
8
+ def unmarshal(source)
9
+ if source.kind_of? REXML::Element
10
+ return Element.new( source )
11
+ else
12
+ return Element.new( REXML::Document.new(source) )
13
+ end
14
+ end
15
+
16
+ def create(tag_name)
17
+ return Element.new(tag_name)
18
+ end
19
+
20
+ class ElementList < Array
21
+ def initialize(parent, name)
22
+ @parent = parent
23
+ @name = name
24
+ end
25
+
26
+ def [](i)
27
+ if i == size
28
+ if i == 1 and !at(0).exists?
29
+ raise "Index out of bounds: (#{i}) when size=#{size}"
30
+ end
31
+ m = Element.new(@name, @parent)
32
+ push m
33
+ return m
34
+ elsif i < size
35
+ return at(i)
36
+ else
37
+ raise "Index out of bounds: (#{i}) when size=#{size}"
38
+ end
39
+ end
40
+
41
+ def []=(i,element)
42
+ if 0 <= i and i < size
43
+ # QUESTION can this be made more efficient?
44
+ rexml = element.to_rexml.dup
45
+ @parent.to_rexml.elements[i+1] = rexml
46
+ fill Element.new(rexml, @parent, true), i, 1
47
+ elsif i = size
48
+ @parent.__attach__ element
49
+ e = Element.new(@name, element)
50
+ push e
51
+ return e
52
+ else
53
+ raise "Index out of bounds: (#{i}) when size=#{size}"
54
+ end
55
+ end
56
+
57
+ def method_missing( name, *args )
58
+ name = name.to_s
59
+ self[0].send( name, *args )
60
+ end
61
+ end
62
+
63
+ class Element
64
+ ATTRIBUTE_RE = /^_/
65
+
66
+ def initialize(source, parent=nil, attached=false)
67
+ if source.kind_of? REXML::Document
68
+ @rexml = source.root
69
+ elsif source.kind_of? REXML::Element
70
+ @rexml = source
71
+ elsif source.kind_of? String
72
+ @rexml = REXML::Element.new(source)
73
+ end
74
+ @parent = parent
75
+ @attached = attached
76
+ end
77
+
78
+ def to_rexml
79
+ return @rexml
80
+ end
81
+
82
+ def get_elements(name)
83
+ out = __create_new_list__ name
84
+ @rexml.each_element( name ) do |elem|
85
+ out.push( __wrap__( elem ) )
86
+ end
87
+ return out
88
+ end
89
+
90
+ def get_attribute(name)
91
+ return @rexml.attributes[ name ].to_s
92
+ end
93
+
94
+ def text
95
+ return @rexml.text
96
+ end
97
+
98
+ def text=(t)
99
+ @rexml.text=t
100
+ if @parent and !@attached
101
+ @parent.__attach__ @rexml
102
+ @attached = true
103
+ end
104
+ end
105
+
106
+ def exists?
107
+ return @attached
108
+ end
109
+
110
+ def __attach__(element)
111
+ @rexml.add element
112
+ if @parent and !@attached
113
+ @parent.__attach__ @rexml
114
+ @attached = true
115
+ end
116
+ end
117
+
118
+ def method_missing(name,*args, &block)
119
+ name = name.to_s
120
+ if name.gsub!(/=$/,"")
121
+ if name.gsub!( ATTRIBUTE_RE, "" )
122
+ @rexml.attributes[name] = args[0]
123
+ else
124
+ elems = self.send(name)
125
+ elems[0] = args[0]
126
+ end
127
+ else
128
+ if name.gsub!( ATTRIBUTE_RE, "" )
129
+ return get_attribute(name)
130
+ else
131
+ elems = get_elements(name)
132
+ if elems.empty?
133
+ e = REXML::Element.new(name)
134
+ elems.push __wrap__(e, false)
135
+ end
136
+ return elems
137
+ end
138
+ end
139
+ end
140
+
141
+ def to_s
142
+ return @rexml.to_s
143
+ end
144
+
145
+ private
146
+ def __create_new_list__(name)
147
+ ElementList.new self, name
148
+ end
149
+
150
+ def __wrap__(elem, attached=true)
151
+ Element.new elem, self, attached
152
+ end
153
+ end
154
+ end
data/tests/test.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'raxb'
2
+ require 'test/unit'
3
+
4
+ include RAXB
5
+
6
+ class SimpleTest < Test::Unit::TestCase
7
+
8
+ def test_0
9
+ test1 = create("test")
10
+ test1.foo.bar.text = 'hello'
11
+ test1.foo.bar[1].text = 'goodbye'
12
+
13
+ doc = REXML::Document.new(test1.to_s)
14
+ test2 = unmarshal(doc)
15
+
16
+ assert_equal 'hello', test2.foo.bar.text
17
+ assert_equal 'goodbye', test2.foo.bar[1].text
18
+ assert_equal test1.to_s, test2.to_s
19
+ end
20
+
21
+ def test_1
22
+ test1 = unmarshal('<test><foo><bar>hello</bar></foo></test>')
23
+ test2 = unmarshal("<test><etc></etc></test>")
24
+
25
+ test2.etc = test1.foo
26
+
27
+ assert_equal test1.to_s, test2.to_s
28
+ assert_equal test2.etc.exists?, false
29
+ end
30
+
31
+ def test_2
32
+ test1 = unmarshal('<test><foo>hello</foo><foo>bonjour</foo></test>')
33
+ test2 = unmarshal("<test><foo>hola</foo></test>")
34
+
35
+ test1.foo[1] = test2.foo
36
+
37
+ assert_equal test1.foo[0].text, 'hello'
38
+ assert_equal test1.foo[1].text, 'hola'
39
+ assert_equal test1.foo[2].exists?, false
40
+ assert_equal test2.foo.text, 'hola'
41
+ end
42
+
43
+ def test_3
44
+ test1 = unmarshal('<test><foo><bar>hello</bar></foo></test>')
45
+ test2 = unmarshal("<test></test>")
46
+
47
+ test2.etc = test1.foo
48
+
49
+ assert_equal test1.to_s, test2.to_s
50
+ assert_equal test2.etc.exists?, false
51
+ end
52
+
53
+ def test_4
54
+ test = unmarshal('<test><foo><bar>hello</bar></foo></test>')
55
+ test.foo._taxi = 'cab'
56
+
57
+ assert_equal test.foo._taxi, 'cab'
58
+ end
59
+
60
+ def test_5
61
+ xml = '<test><foo><bar>hello</bar></foo></test>'
62
+ raxb = unmarshal(xml)
63
+ rexml = REXML::Document.new(xml)
64
+
65
+ assert_equal raxb.to_rexml.to_s, rexml.to_s
66
+
67
+ rexml2 = REXML::Document.new
68
+ rexml2.add raxb.to_rexml
69
+
70
+ assert_equal rexml.to_s, rexml2.to_s
71
+ end
72
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: raxb
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2008-03-18 00:00:00 -05:00
8
+ summary: Ruby API for XML Binding
9
+ require_paths:
10
+ - lib
11
+ email: jpkutner@gmail.com
12
+ homepage: http://raxb.rubyforge.org
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: raxb
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.8.2
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Joe Kutner
31
+ files:
32
+ - lib/raxb.rb
33
+ test_files:
34
+ - tests/test.rb
35
+ rdoc_options: []
36
+
37
+ extra_rdoc_files: []
38
+
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ requirements: []
44
+
45
+ dependencies: []
46
+