oxm 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/CHANGELOG.markdown +15 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +25 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +81 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/oxm/object.rb +154 -0
- data/lib/oxm/sax_handler.rb +57 -0
- data/lib/oxm.rb +16 -0
- data/test/helper.rb +17 -0
- data/test/test_oxm.rb +166 -0
- metadata +118 -0
data/.document
ADDED
data/CHANGELOG.markdown
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
### 0.1.0 / 2011/09/19
|
2
|
+
* Disclaimer: Not compatible to the previous versions
|
3
|
+
** Removed: OXM::Object#cdata, OXM::Object#text, OXM::Object#text=
|
4
|
+
** Added: OXM::Object#content, OXM::Object#content=
|
5
|
+
** Changed: OXM::Object#to_s never returns nil
|
6
|
+
** Changed: OXM::Object#compact! removes empty elements as well (no text value, no attributes at all)
|
7
|
+
** Fix: Allows assignment of nil/empty string as element values
|
8
|
+
|
9
|
+
### 0.0.2 / 2011/09/15
|
10
|
+
* OXM::Object#compact! added
|
11
|
+
* OXM::Object#elements as an alias of OXM::Object#children
|
12
|
+
|
13
|
+
### 0.0.1 / 2011/09/15
|
14
|
+
* Initial release
|
15
|
+
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "bundler", "~> 1.0.0"
|
10
|
+
gem "jeweler", "~> 1.6.4"
|
11
|
+
gem "rcov", ">= 0"
|
12
|
+
end
|
13
|
+
|
14
|
+
gem "builder", ">= 3.0.0"
|
15
|
+
gem "nokogiri", ">= 1.5.0"
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
builder (3.0.0)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.6.4)
|
7
|
+
bundler (~> 1.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
nokogiri (1.5.0)
|
11
|
+
nokogiri (1.5.0-java)
|
12
|
+
rake (0.9.2)
|
13
|
+
rcov (0.9.10)
|
14
|
+
rcov (0.9.10-java)
|
15
|
+
|
16
|
+
PLATFORMS
|
17
|
+
java
|
18
|
+
ruby
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
builder (>= 3.0.0)
|
22
|
+
bundler (~> 1.0.0)
|
23
|
+
jeweler (~> 1.6.4)
|
24
|
+
nokogiri (>= 1.5.0)
|
25
|
+
rcov
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Junegunn Choi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# oxm
|
2
|
+
|
3
|
+
A tiny, easy-to-use Object-XML-Mapper for Ruby.
|
4
|
+
Internally uses Nokogiri SAX parser which allows handling of large XML documents.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
```
|
9
|
+
gem install oxm
|
10
|
+
```
|
11
|
+
|
12
|
+
## Examples
|
13
|
+
|
14
|
+
```xml
|
15
|
+
<orders>
|
16
|
+
<order date="2011/08/27">
|
17
|
+
<item amount="5">Apple</item>
|
18
|
+
<item amount="2">Banana</item>
|
19
|
+
<customer id="100">Alice</customer>
|
20
|
+
</order>
|
21
|
+
<order date="2011/08/27">
|
22
|
+
<item amount="1">Zoltax</item>
|
23
|
+
<customer id="200">Bob</customer>
|
24
|
+
</order>
|
25
|
+
</orders>
|
26
|
+
```
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'oxm'
|
30
|
+
|
31
|
+
# With block
|
32
|
+
OXM.from_xml(xml_data_or_io, 'orders/order') do |order|
|
33
|
+
# Accessing attributes of the element
|
34
|
+
order['date']
|
35
|
+
order.attributes
|
36
|
+
|
37
|
+
# Accessing attributes and text/cdata values of child elements
|
38
|
+
order.item.first['amount']
|
39
|
+
order.item.first.content
|
40
|
+
order.item.first.to_s
|
41
|
+
order.item.first.cdata?
|
42
|
+
|
43
|
+
# Traverses child elements
|
44
|
+
order.elements.each do |tag, elements_for_the_tag|
|
45
|
+
# ...
|
46
|
+
end
|
47
|
+
|
48
|
+
# Compaction: collapse single-element Arrays
|
49
|
+
order.customer.first.to_s
|
50
|
+
order.customer.first['id']
|
51
|
+
order.compact!
|
52
|
+
order.customer.to_s
|
53
|
+
order.customer['id']
|
54
|
+
|
55
|
+
# XML expression for the element
|
56
|
+
order.to_xml
|
57
|
+
order.item.first.to_xml
|
58
|
+
end
|
59
|
+
|
60
|
+
# Array of elements are returned when block is not given
|
61
|
+
items = OXM.from_xml(xml_data_or_io, 'orders/order/item')
|
62
|
+
```
|
63
|
+
|
64
|
+
## TODO
|
65
|
+
* When block is not given, make from_xml return an Enumerator instead of an Array
|
66
|
+
|
67
|
+
## Contributing to oxm
|
68
|
+
|
69
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
70
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
71
|
+
* Fork the project
|
72
|
+
* Start a feature/bugfix branch
|
73
|
+
* Commit and push until you are happy with your contribution
|
74
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
75
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
76
|
+
|
77
|
+
## Copyright
|
78
|
+
|
79
|
+
Copyright (c) 2011 Junegunn Choi. See LICENSE.txt for
|
80
|
+
further details.
|
81
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "oxm"
|
18
|
+
gem.homepage = "http://github.com/junegunn/oxm"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{A tiny Object-XML-Mapper}
|
21
|
+
gem.description = %Q{A tiny Object-XML-Mapper using Nokogiri SAX parser}
|
22
|
+
gem.email = "junegunn.c@gmail.com"
|
23
|
+
gem.authors = ["Junegunn Choi"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
Rcov::RcovTask.new do |test|
|
37
|
+
test.libs << 'test'
|
38
|
+
test.pattern = 'test/**/test_*.rb'
|
39
|
+
test.verbose = true
|
40
|
+
test.rcov_opts << '--exclude "gems/*"'
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "oxm #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/oxm/object.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
module OXM
|
2
|
+
class Object
|
3
|
+
attr_reader :tag
|
4
|
+
|
5
|
+
# @return [String/NilClass]
|
6
|
+
def content
|
7
|
+
@data
|
8
|
+
end
|
9
|
+
|
10
|
+
# @param [String] val Text
|
11
|
+
# @param [String] val
|
12
|
+
# @return [String]
|
13
|
+
def content= val
|
14
|
+
@cdata = false
|
15
|
+
process val
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [String] val CDATA content
|
19
|
+
# @return [String]
|
20
|
+
def cdata= val
|
21
|
+
@cdata = true
|
22
|
+
process val
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean]
|
26
|
+
def cdata?
|
27
|
+
@cdata
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] XML expression for this object
|
31
|
+
def to_xml
|
32
|
+
io = StringIO.new
|
33
|
+
builder = Builder::XmlMarkup.new(:target => io)
|
34
|
+
|
35
|
+
build_node = lambda do |node|
|
36
|
+
builder.tag!(node.tag, node.attributes) do
|
37
|
+
node.elements.each do |tag, elements|
|
38
|
+
next if elements.nil?
|
39
|
+
elements = [elements] unless elements.is_a? Array
|
40
|
+
elements.each do |child|
|
41
|
+
build_node.call child
|
42
|
+
end
|
43
|
+
end
|
44
|
+
if node.content
|
45
|
+
if node.cdata?
|
46
|
+
builder.cdata! node.content
|
47
|
+
else
|
48
|
+
builder.text! node.content
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
build_node.call self
|
55
|
+
io.string
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [String]
|
59
|
+
def to_s
|
60
|
+
@data.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [String]
|
64
|
+
def inspect
|
65
|
+
to_xml
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param [String] attr
|
69
|
+
# @return [String]
|
70
|
+
def [] attr
|
71
|
+
@attrs[attr.to_s]
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param [String] attr
|
75
|
+
# @param [String] val
|
76
|
+
# @return [String]
|
77
|
+
def []= attr, val
|
78
|
+
@attrs[attr.to_s] = val
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [Hash]
|
82
|
+
def attributes
|
83
|
+
@attrs
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [Hash]
|
87
|
+
def elements
|
88
|
+
@nodes
|
89
|
+
end
|
90
|
+
alias children elements
|
91
|
+
|
92
|
+
# @param [String] tag
|
93
|
+
# @param [OXM::Object] object
|
94
|
+
# @return [OXM::Object]
|
95
|
+
def add_node tag, object
|
96
|
+
@nodes[tag] ||= []
|
97
|
+
@nodes[tag] << object
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
# Compacts the object by removing empty child elements and then collapsing element Arrays.
|
102
|
+
# After compaction, single-element arrays are collapsed, and empty arrays become nil.
|
103
|
+
# @return [OXM::Object]
|
104
|
+
def compact!
|
105
|
+
@nodes.each do |key, value|
|
106
|
+
if value.is_a?(Array)
|
107
|
+
value = value.reject(&:empty?)
|
108
|
+
@nodes[key] =
|
109
|
+
case value.length
|
110
|
+
when 0
|
111
|
+
nil
|
112
|
+
when 1
|
113
|
+
value.first
|
114
|
+
else
|
115
|
+
value
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
# @param [String] tag
|
123
|
+
# @param [Hash] attrs
|
124
|
+
# @return [OXM::Object]
|
125
|
+
def initialize tag, attrs = {}
|
126
|
+
@tag = tag
|
127
|
+
@attrs = attrs
|
128
|
+
@nodes = {}
|
129
|
+
@cdata = false
|
130
|
+
@data = nil
|
131
|
+
end
|
132
|
+
|
133
|
+
# @return [Boolean] Return if the element is empty (no text value and no attributes)
|
134
|
+
def empty?
|
135
|
+
self.to_s.empty? && self.attributes.empty?
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
def method_missing(symb, *args)
|
140
|
+
if @nodes.has_key?(symb.to_s)
|
141
|
+
return @nodes[symb.to_s]
|
142
|
+
else
|
143
|
+
raise NoMethodError.new("undefined method or attribute `#{symb}'")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def process str
|
148
|
+
str = str.to_s.strip
|
149
|
+
@data = str
|
150
|
+
end
|
151
|
+
|
152
|
+
end#Object
|
153
|
+
end#OXM
|
154
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module OXM
|
2
|
+
class SaxHandler < Nokogiri::XML::SAX::Document
|
3
|
+
attr_reader :outputs
|
4
|
+
|
5
|
+
def initialize loop_node, &block
|
6
|
+
@loop_node = loop_node
|
7
|
+
@block = block
|
8
|
+
@tags = []
|
9
|
+
@objects = []
|
10
|
+
@outputs = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def start_element tag, attributes
|
14
|
+
@tags << tag
|
15
|
+
|
16
|
+
# Met loop element
|
17
|
+
if @objects.empty?
|
18
|
+
if match?
|
19
|
+
@objects << @object = OXM::Object.new(tag, Hash[*attributes.flatten])
|
20
|
+
end
|
21
|
+
elsif @object
|
22
|
+
@object.add_node tag, node_obj = OXM::Object.new(tag, Hash[*attributes.flatten])
|
23
|
+
@objects << @object = node_obj
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def cdata_block str
|
28
|
+
@object.cdata = @object.to_s + str if @object
|
29
|
+
end
|
30
|
+
|
31
|
+
def characters str
|
32
|
+
@object.content = @object.to_s + str if @object
|
33
|
+
end
|
34
|
+
|
35
|
+
def end_element tag
|
36
|
+
unless @objects.empty?
|
37
|
+
if match?
|
38
|
+
obj = @objects.pop
|
39
|
+
if @block
|
40
|
+
@block.call obj
|
41
|
+
else
|
42
|
+
@outputs << obj
|
43
|
+
end
|
44
|
+
@object = nil
|
45
|
+
else
|
46
|
+
@objects.pop
|
47
|
+
@object = @objects.last
|
48
|
+
end
|
49
|
+
end
|
50
|
+
@tags.pop
|
51
|
+
end
|
52
|
+
|
53
|
+
def match?
|
54
|
+
@tags.join('/') == @loop_node
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end#OXM
|
data/lib/oxm.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'builder'
|
3
|
+
require 'oxm/sax_handler'
|
4
|
+
require 'oxm/object'
|
5
|
+
|
6
|
+
module OXM
|
7
|
+
# @param [IO/String] xml XML data
|
8
|
+
# @param [String] loop_element
|
9
|
+
# @return [Array] Array of OXM::Objects
|
10
|
+
def self.from_xml xml, loop_element, &block
|
11
|
+
handler = OXM::SaxHandler.new(loop_element, &block)
|
12
|
+
parser = Nokogiri::XML::SAX::Parser.new(handler)
|
13
|
+
parser.parse xml
|
14
|
+
handler.outputs unless block_given?
|
15
|
+
end
|
16
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
require 'oxm'
|
15
|
+
|
16
|
+
class Test::Unit::TestCase
|
17
|
+
end
|
data/test/test_oxm.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestOxm < Test::Unit::TestCase
|
4
|
+
def test_from_xml_string
|
5
|
+
str = <<-EOF
|
6
|
+
<container attr1="1" attr2="2">
|
7
|
+
<item dept="A">
|
8
|
+
<volume unit="ml"><![CDATA[ 100 ]]></volume>
|
9
|
+
<volume unit="ml"><![CDATA[200]]></volume>
|
10
|
+
</item>
|
11
|
+
<item dept="B">
|
12
|
+
<volume unit="l">200</volume>
|
13
|
+
<volume unit="l">300</volume>
|
14
|
+
</item>
|
15
|
+
<item dept="C">
|
16
|
+
<volume unit="l">300</volume>
|
17
|
+
<volume unit="ml">400</volume>
|
18
|
+
</item>
|
19
|
+
<item dept="D">
|
20
|
+
<volume unit="L">500</volume>
|
21
|
+
<volume></volume>
|
22
|
+
</item>
|
23
|
+
</container>
|
24
|
+
EOF
|
25
|
+
|
26
|
+
require 'tempfile'
|
27
|
+
tf = Tempfile.new('oxm')
|
28
|
+
tf << str
|
29
|
+
tf.flush
|
30
|
+
|
31
|
+
[str, File.open(tf.path)].each do |input|
|
32
|
+
result = OXM.from_xml(input, 'container')
|
33
|
+
assert result.is_a?(Array)
|
34
|
+
assert_equal 1, result.length
|
35
|
+
assert_equal "", result.first.to_s
|
36
|
+
assert_equal({'attr1' => '1', 'attr2' => '2'}, result.first.attributes)
|
37
|
+
assert_equal(result.first.children, result.first.elements)
|
38
|
+
assert_equal(%w[item], result.first.children.keys)
|
39
|
+
assert_equal(4, result.first.elements.values.first.length)
|
40
|
+
assert_equal '1', result.first['attr1']
|
41
|
+
assert_equal '2', result.first['attr2']
|
42
|
+
assert_equal nil, result.first['attr3']
|
43
|
+
|
44
|
+
assert result.map(&:item).all? { |items| items.is_a? Array }
|
45
|
+
assert result.map(&:item).map(&:first).all? { |i| i.tag == 'item' }
|
46
|
+
assert result.first.item.first.volume.all? { |i| i.cdata? }
|
47
|
+
assert result.first.item.first.volume.all? { |i| i.content == i.to_s }
|
48
|
+
assert result.first.item.last.volume.all? { |i| i.cdata? == false }
|
49
|
+
|
50
|
+
container = result.first
|
51
|
+
assert container.compact!.equal?(container) # Object identity
|
52
|
+
assert container.item.is_a?(Array)
|
53
|
+
|
54
|
+
result = OXM.from_xml(str, 'container/item')
|
55
|
+
assert_equal 4, result.length
|
56
|
+
|
57
|
+
item = result.last
|
58
|
+
item.compact!
|
59
|
+
assert item.volume.is_a?(OXM::Object)
|
60
|
+
assert_equal '500', item.volume.to_s
|
61
|
+
assert_equal 'L', item.volume['unit']
|
62
|
+
|
63
|
+
result = OXM.from_xml(str, 'container/item/volume')
|
64
|
+
assert_equal 8, result.length
|
65
|
+
assert_equal %w[100 200 200 300 300 400 500] + [""], result.map(&:to_s)
|
66
|
+
assert_equal %w[ml ml l l l ml L] + [nil], result.map { |e| e['unit'] }
|
67
|
+
assert_equal result.map { |e| e['unit'] }, result.map { |e| e[:unit] }
|
68
|
+
assert_equal '<volume unit="ml"><![CDATA[100]]></volume>', result.first.to_xml
|
69
|
+
|
70
|
+
vol = result[-3]
|
71
|
+
assert_equal '<volume unit="ml">400</volume>', vol.to_xml
|
72
|
+
vol['unit'] = 'L'
|
73
|
+
assert_equal '<volume unit="L">400</volume>', vol.to_xml
|
74
|
+
vol.content = 500
|
75
|
+
assert_equal '<volume unit="L">500</volume>', vol.to_xml
|
76
|
+
vol.content = 550
|
77
|
+
assert_equal '<volume unit="L">550</volume>', vol.to_xml
|
78
|
+
vol.cdata = 600
|
79
|
+
assert_equal '<volume unit="L"><![CDATA[600]]></volume>', vol.to_xml
|
80
|
+
vol.cdata = 660
|
81
|
+
assert_equal '<volume unit="L"><![CDATA[660]]></volume>', vol.to_xml
|
82
|
+
|
83
|
+
long_str = "_" * 1000000
|
84
|
+
vol.content = long_str
|
85
|
+
assert_equal '<volume unit="L">' + long_str + '</volume>', vol.to_xml
|
86
|
+
|
87
|
+
vol.cdata = long_str
|
88
|
+
assert_equal '<volume unit="L"><![CDATA[' + long_str + ']]></volume>', vol.to_xml
|
89
|
+
|
90
|
+
vol.cdata = ""
|
91
|
+
assert_equal '<volume unit="L"><![CDATA[]]></volume>', vol.to_xml
|
92
|
+
|
93
|
+
# invalid stripping might occur
|
94
|
+
long_str = "_" + ' ' * 1000000 + '_'
|
95
|
+
vol.content = long_str
|
96
|
+
assert_equal '<volume unit="L">' + long_str + '</volume>', vol.to_xml
|
97
|
+
|
98
|
+
vol.content = nil
|
99
|
+
assert_equal '<volume unit="L"></volume>', vol.to_xml
|
100
|
+
|
101
|
+
cnt = 0
|
102
|
+
result = OXM.from_xml(str, 'container/item/volume') do |obj|
|
103
|
+
assert_equal 'volume', obj.tag
|
104
|
+
assert obj.is_a?(OXM::Object)
|
105
|
+
cnt += 1
|
106
|
+
end
|
107
|
+
assert_equal 8, cnt
|
108
|
+
assert_nil result
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_compaction
|
113
|
+
str = <<-EOF
|
114
|
+
<container attr1="1" attr2="2">
|
115
|
+
<item dept="array">
|
116
|
+
<volume unit="ml"><![CDATA[ 100 ]]></volume>
|
117
|
+
<volume unit="ml"><![CDATA[200]]></volume>
|
118
|
+
</item>
|
119
|
+
|
120
|
+
<item dept="single">
|
121
|
+
<volume unit="l">200</volume>
|
122
|
+
</item>
|
123
|
+
|
124
|
+
<item dept="single">
|
125
|
+
<volume unit="ML"></volume>
|
126
|
+
</item>
|
127
|
+
|
128
|
+
<item dept="single">
|
129
|
+
<volume unit="l">200</volume>
|
130
|
+
<volume></volume>
|
131
|
+
</item>
|
132
|
+
|
133
|
+
<item dept="nil">
|
134
|
+
<volume></volume>
|
135
|
+
<volume></volume>
|
136
|
+
</item>
|
137
|
+
</container>
|
138
|
+
EOF
|
139
|
+
|
140
|
+
items = OXM.from_xml(str, 'container/item')
|
141
|
+
assert_equal 5, items.length
|
142
|
+
|
143
|
+
items[0].compact!
|
144
|
+
assert_equal Array, items[0].volume.class
|
145
|
+
|
146
|
+
items[1].compact!
|
147
|
+
assert_equal OXM::Object, items[1].volume.class
|
148
|
+
|
149
|
+
items[2].compact!
|
150
|
+
assert_equal OXM::Object, items[2].volume.class
|
151
|
+
assert_equal nil, items[2].volume.content
|
152
|
+
assert_equal 'ML', items[2].volume['unit']
|
153
|
+
|
154
|
+
items[3].compact!
|
155
|
+
assert_equal OXM::Object, items[3].volume.class
|
156
|
+
assert_equal '<item dept="single"><volume unit="l">200</volume></item>', items[3].inspect
|
157
|
+
assert_equal "200", items[3].volume.content
|
158
|
+
|
159
|
+
items[4].compact!
|
160
|
+
assert_equal nil, items[4].volume
|
161
|
+
|
162
|
+
assert_raise(NoMethodError) {
|
163
|
+
items[4].voll
|
164
|
+
}
|
165
|
+
end
|
166
|
+
end
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oxm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Junegunn Choi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-19 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: builder
|
16
|
+
requirement: &2160763840 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2160763840
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: nokogiri
|
27
|
+
requirement: &2160755540 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.5.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2160755540
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: bundler
|
38
|
+
requirement: &2160753840 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.0.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2160753840
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: jeweler
|
49
|
+
requirement: &2160752880 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.6.4
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2160752880
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rcov
|
60
|
+
requirement: &2160752000 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2160752000
|
69
|
+
description: A tiny Object-XML-Mapper using Nokogiri SAX parser
|
70
|
+
email: junegunn.c@gmail.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- LICENSE.txt
|
75
|
+
- README.markdown
|
76
|
+
files:
|
77
|
+
- .document
|
78
|
+
- CHANGELOG.markdown
|
79
|
+
- Gemfile
|
80
|
+
- Gemfile.lock
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.markdown
|
83
|
+
- Rakefile
|
84
|
+
- VERSION
|
85
|
+
- lib/oxm.rb
|
86
|
+
- lib/oxm/object.rb
|
87
|
+
- lib/oxm/sax_handler.rb
|
88
|
+
- test/helper.rb
|
89
|
+
- test/test_oxm.rb
|
90
|
+
homepage: http://github.com/junegunn/oxm
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
hash: 1267901525051297766
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 1.8.6
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: A tiny Object-XML-Mapper
|
118
|
+
test_files: []
|