raxb 0.1
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/lib/raxb.rb +154 -0
- data/tests/test.rb +72 -0
- 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
|
+
|