multi_xml 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of multi_xml might be problematic. Click here for more details.
- data/.gitignore +3 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +25 -0
- data/LICENSE +20 -0
- data/README.rdoc +32 -0
- data/Rakefile +28 -0
- data/lib/multi_xml.rb +65 -0
- data/lib/multi_xml/engines/rexml.rb +221 -0
- data/lib/multi_xml/version.rb +3 -0
- data/multi_xml.gemspec +25 -0
- data/spec/multi_xml_spec.rb +50 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +16 -0
- metadata +177 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
multi_xml (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
hpricot (0.8.2)
|
10
|
+
libxml-ruby (1.1.4)
|
11
|
+
nokogiri (1.4.3.1)
|
12
|
+
rake (0.8.7)
|
13
|
+
rspec (1.3.0)
|
14
|
+
|
15
|
+
PLATFORMS
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
bundler (~> 1.0.2)
|
20
|
+
hpricot (~> 0.8.2)
|
21
|
+
libxml-ruby (~> 1.1.4)
|
22
|
+
multi_xml!
|
23
|
+
nokogiri (~> 1.4.3)
|
24
|
+
rake (~> 0.8.7)
|
25
|
+
rspec (~> 1.3.0)
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Erik Michaels-Ober
|
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.rdoc
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
= MultiXML
|
2
|
+
|
3
|
+
Lots of Ruby libraries utilize XML parsing in some form, and everyone has their favorite XML library. In order to best support multiple XML parsers and libraries, <tt>multi_xml</tt> is a general-purpose swappable XML backend library. You use it like so:
|
4
|
+
|
5
|
+
require 'multi_xml'
|
6
|
+
|
7
|
+
MultiXml.engine = :nokogiri
|
8
|
+
MultiXml.parse('<tag>This is the contents</tag>') # parsed using Nokogiri
|
9
|
+
|
10
|
+
MultiXml.engine = :rexml
|
11
|
+
MultiXml.engine = MultiJson::Engines::Rexml # equivalent to previous line
|
12
|
+
MultiXml.parse('<tag>This is the contents</tag>') # parsed using REXML
|
13
|
+
|
14
|
+
The <tt>engine</tt> setter takes either a symbol or a class (to allow for custom XML parsers) that responds to <tt>.parse</tt> at the class level.
|
15
|
+
|
16
|
+
MultiXML tries to have intelligent defaulting. That is, if you have any of the supported engines already loaded, it will utilize them before attempting to load any. When loading, libraries are ordered by speed. First LibXML, then Nokogiri, then Hpricot, then REXML.
|
17
|
+
|
18
|
+
== Inspriation
|
19
|
+
|
20
|
+
MultiXML was inspired by MultiJSON[http://github.com/intridea/multi_json/].
|
21
|
+
|
22
|
+
== Submitting Patches
|
23
|
+
|
24
|
+
1. Fork the project.
|
25
|
+
2. Commit your feature or bug fix.
|
26
|
+
3. Add tests for it. This is important so it doesn't break in the future.
|
27
|
+
4. Do not mess with gemspec, version, or history. (If you want to have your own version, that's fine, but please do so in a separate commit.)
|
28
|
+
5. Submit a pull request. Bonus points for topic branches.
|
29
|
+
|
30
|
+
== Copyright
|
31
|
+
|
32
|
+
Copyright (c) 2010 Erik Michaels-Ober. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
Rake::RDocTask.new do |rdoc|
|
10
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
11
|
+
rdoc.rdoc_dir = 'rdoc'
|
12
|
+
rdoc.title = "multi_xml #{version}"
|
13
|
+
rdoc.rdoc_files.include('README*')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
18
|
+
spec.libs << 'lib' << 'spec'
|
19
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
20
|
+
end
|
21
|
+
|
22
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
23
|
+
spec.libs << 'lib' << 'spec'
|
24
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
25
|
+
spec.rcov = true
|
26
|
+
end
|
27
|
+
|
28
|
+
task :default => :spec
|
data/lib/multi_xml.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module MultiXml
|
2
|
+
module_function
|
3
|
+
|
4
|
+
# Get the current engine class.
|
5
|
+
def engine
|
6
|
+
return @engine if @engine
|
7
|
+
self.engine = self.default_engine
|
8
|
+
@engine
|
9
|
+
end
|
10
|
+
|
11
|
+
REQUIREMENT_MAP = [
|
12
|
+
['libxml', :libxml],
|
13
|
+
['nokogiri', :nokogiri],
|
14
|
+
['hpricot', :hpricot],
|
15
|
+
['rexml/document', :rexml]
|
16
|
+
]
|
17
|
+
|
18
|
+
# The default engine based on what you currently
|
19
|
+
# have loaded and installed. First checks to see
|
20
|
+
# if any engines are already loaded, then checks
|
21
|
+
# to see which are installed if none are loaded.
|
22
|
+
def default_engine
|
23
|
+
return :libxml if defined?(::LibXML)
|
24
|
+
return :nokogiri if defined?(::Nokogiri)
|
25
|
+
return :hpricot if defined?(::Hpricot)
|
26
|
+
|
27
|
+
REQUIREMENT_MAP.each do |(library, engine)|
|
28
|
+
begin
|
29
|
+
require library
|
30
|
+
return engine
|
31
|
+
rescue LoadError
|
32
|
+
next
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the XML parser utilizing a symbol, string, or class.
|
38
|
+
# Supported by default are:
|
39
|
+
#
|
40
|
+
# * <tt>:libxml</tt>
|
41
|
+
# * <tt>:nokogiri</tt>
|
42
|
+
# * <tt>:hpricot</tt>
|
43
|
+
# * <tt>:rexml</tt>
|
44
|
+
def engine=(new_engine)
|
45
|
+
case new_engine
|
46
|
+
when String, Symbol
|
47
|
+
require "multi_xml/engines/#{new_engine}"
|
48
|
+
@engine = MultiXml::Engines.const_get("#{new_engine.to_s.split('_').map{|s| s.capitalize}.join('')}")
|
49
|
+
when Class
|
50
|
+
@engine = new_engine
|
51
|
+
else
|
52
|
+
raise "Did not recognize your engine specification. Please specify either a symbol or a class."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Parse a XML string into Ruby.
|
57
|
+
#
|
58
|
+
# <b>Options</b>
|
59
|
+
#
|
60
|
+
# <tt>:symbolize_keys</tt> :: If true, will use symbols instead of strings for the keys.
|
61
|
+
def parse(string, options = {})
|
62
|
+
engine.parse(string, options)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require 'rexml/parsers/baseparser'
|
2
|
+
require 'rexml/text'
|
3
|
+
require 'date'
|
4
|
+
require 'time'
|
5
|
+
require 'yaml'
|
6
|
+
require 'bigdecimal'
|
7
|
+
|
8
|
+
module MultiXml
|
9
|
+
module Engines
|
10
|
+
# Use REXML to parse XML.
|
11
|
+
class Rexml
|
12
|
+
|
13
|
+
def self.parse(string, options = {}) #:nodoc:
|
14
|
+
string.strip!
|
15
|
+
stack = []
|
16
|
+
parser = ::REXML::Parsers::BaseParser.new(string)
|
17
|
+
|
18
|
+
while true
|
19
|
+
event = parser.pull
|
20
|
+
case event[0]
|
21
|
+
when :end_document
|
22
|
+
break
|
23
|
+
when :start_element
|
24
|
+
stack.push RexmlUtilityNode.new(event[1], event[2])
|
25
|
+
when :end_element
|
26
|
+
if stack.size > 1
|
27
|
+
temp = stack.pop
|
28
|
+
stack.last.add_node(temp)
|
29
|
+
end
|
30
|
+
when :text, :cdata
|
31
|
+
stack.last.add_node(event[1]) unless event[1].strip.length == 0 || stack.empty?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
hash = (stack.length > 0 ? stack.pop.to_hash : {})
|
35
|
+
options[:symbolize_keys] ? symbolize_keys(hash) : hash
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.symbolize_keys(hash) #:nodoc:
|
39
|
+
hash.inject({}){|result, (key, value)|
|
40
|
+
new_key = case key
|
41
|
+
when String then key.to_sym
|
42
|
+
else key
|
43
|
+
end
|
44
|
+
new_value = case value
|
45
|
+
when Hash then symbolize_keys(value)
|
46
|
+
else value
|
47
|
+
end
|
48
|
+
result[new_key] = new_value
|
49
|
+
result
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class RexmlUtilityNode #:nodoc:
|
55
|
+
attr_accessor :name, :attributes, :children, :type
|
56
|
+
|
57
|
+
def self.typecasts
|
58
|
+
@@typecasts
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.typecasts=(obj)
|
62
|
+
@@typecasts = obj
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.available_typecasts
|
66
|
+
@@available_typecasts
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.available_typecasts=(obj)
|
70
|
+
@@available_typecasts = obj
|
71
|
+
end
|
72
|
+
|
73
|
+
self.typecasts = {}
|
74
|
+
self.typecasts["integer"] = lambda{|v| v.nil? ? nil : v.to_i}
|
75
|
+
self.typecasts["boolean"] = lambda{|v| v.nil? ? nil : (v.strip != "false")}
|
76
|
+
self.typecasts["datetime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc}
|
77
|
+
self.typecasts["date"] = lambda{|v| v.nil? ? nil : Date.parse(v)}
|
78
|
+
self.typecasts["dateTime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc}
|
79
|
+
self.typecasts["decimal"] = lambda{|v| v.nil? ? nil : BigDecimal(v.to_s)}
|
80
|
+
self.typecasts["double"] = lambda{|v| v.nil? ? nil : v.to_f}
|
81
|
+
self.typecasts["float"] = lambda{|v| v.nil? ? nil : v.to_f}
|
82
|
+
self.typecasts["symbol"] = lambda{|v| v.nil? ? nil : v.to_sym}
|
83
|
+
self.typecasts["string"] = lambda{|v| v.to_s}
|
84
|
+
self.typecasts["yaml"] = lambda{|v| v.nil? ? nil : YAML.load(v)}
|
85
|
+
self.typecasts["base64Binary"] = lambda{|v| v.unpack('m').first }
|
86
|
+
|
87
|
+
self.available_typecasts = self.typecasts.keys
|
88
|
+
|
89
|
+
def initialize(name, normalized_attributes = {})
|
90
|
+
|
91
|
+
# unnormalize attribute values
|
92
|
+
attributes = Hash[* normalized_attributes.map { |key, value|
|
93
|
+
[ key, unnormalize_xml_entities(value) ]
|
94
|
+
}.flatten]
|
95
|
+
|
96
|
+
@name = name.tr("-", "_")
|
97
|
+
# leave the type alone if we don't know what it is
|
98
|
+
@type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
|
99
|
+
|
100
|
+
@nil_element = attributes.delete("nil") == "true"
|
101
|
+
@attributes = undasherize_keys(attributes)
|
102
|
+
@children = []
|
103
|
+
@text = false
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_node(node)
|
107
|
+
@text = true if node.is_a? String
|
108
|
+
@children << node
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_hash
|
112
|
+
if @type == "file"
|
113
|
+
f = StringIO.new((@children.first || '').unpack('m').first)
|
114
|
+
class << f
|
115
|
+
attr_accessor :original_filename, :content_type
|
116
|
+
end
|
117
|
+
f.original_filename = attributes['name'] || 'untitled'
|
118
|
+
f.content_type = attributes['content_type'] || 'application/octet-stream'
|
119
|
+
return {name => f}
|
120
|
+
end
|
121
|
+
|
122
|
+
if @text
|
123
|
+
t = typecast_value( unnormalize_xml_entities( inner_html ) )
|
124
|
+
t.class.send(:attr_accessor, :attributes)
|
125
|
+
t.attributes = attributes
|
126
|
+
return { name => t }
|
127
|
+
else
|
128
|
+
#change repeating groups into an array
|
129
|
+
groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s }
|
130
|
+
|
131
|
+
out = nil
|
132
|
+
if @type == "array"
|
133
|
+
out = []
|
134
|
+
groups.each do |k, v|
|
135
|
+
if v.size == 1
|
136
|
+
out << v.first.to_hash.entries.first.last
|
137
|
+
else
|
138
|
+
out << v.map{|e| e.to_hash[k]}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
out = out.flatten
|
142
|
+
|
143
|
+
else # If Hash
|
144
|
+
out = {}
|
145
|
+
groups.each do |k,v|
|
146
|
+
if v.size == 1
|
147
|
+
out.merge!(v.first)
|
148
|
+
else
|
149
|
+
out.merge!( k => v.map{|e| e.to_hash[k]})
|
150
|
+
end
|
151
|
+
end
|
152
|
+
out.merge! attributes unless attributes.empty?
|
153
|
+
out = out.empty? ? nil : out
|
154
|
+
end
|
155
|
+
|
156
|
+
if @type && out.nil?
|
157
|
+
{ name => typecast_value(out) }
|
158
|
+
else
|
159
|
+
{ name => out }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Typecasts a value based upon its type. For instance, if
|
165
|
+
# +node+ has #type == "integer",
|
166
|
+
# {{[node.typecast_value("12") #=> 12]}}
|
167
|
+
#
|
168
|
+
# @param value<String> The value that is being typecast.
|
169
|
+
#
|
170
|
+
# @details [:type options]
|
171
|
+
# "integer"::
|
172
|
+
# converts +value+ to an integer with #to_i
|
173
|
+
# "boolean"::
|
174
|
+
# checks whether +value+, after removing spaces, is the literal
|
175
|
+
# "true"
|
176
|
+
# "datetime"::
|
177
|
+
# Parses +value+ using Time.parse, and returns a UTC Time
|
178
|
+
# "date"::
|
179
|
+
# Parses +value+ using Date.parse
|
180
|
+
#
|
181
|
+
# @return <Integer, TrueClass, FalseClass, Time, Date, Object>
|
182
|
+
# The result of typecasting +value+.
|
183
|
+
#
|
184
|
+
# @note
|
185
|
+
# If +self+ does not have a "type" key, or if it's not one of the
|
186
|
+
# options specified above, the raw +value+ will be returned.
|
187
|
+
def typecast_value(value)
|
188
|
+
return value unless @type
|
189
|
+
proc = self.class.typecasts[@type]
|
190
|
+
proc.nil? ? value : proc.call(value)
|
191
|
+
end
|
192
|
+
|
193
|
+
# Take keys of the form foo-bar and convert them to foo_bar
|
194
|
+
def undasherize_keys(params)
|
195
|
+
params.keys.each do |key, value|
|
196
|
+
params[key.tr("-", "_")] = params.delete(key)
|
197
|
+
end
|
198
|
+
params
|
199
|
+
end
|
200
|
+
|
201
|
+
# Get the inner_html of the REXML node.
|
202
|
+
def inner_html
|
203
|
+
@children.join
|
204
|
+
end
|
205
|
+
|
206
|
+
# Converts the node into a readable HTML node.
|
207
|
+
#
|
208
|
+
# @return <String> The HTML node in text form.
|
209
|
+
def to_html
|
210
|
+
attributes.merge!(:type => @type ) if @type
|
211
|
+
"<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
|
212
|
+
end
|
213
|
+
alias :to_s :to_html
|
214
|
+
|
215
|
+
def unnormalize_xml_entities value
|
216
|
+
::REXML::Text.unnormalize(value)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
end
|
data/multi_xml.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "multi_xml/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.add_development_dependency("bundler", ["~> 1.0.2"])
|
7
|
+
s.add_development_dependency("hpricot", ["~> 0.8.2"])
|
8
|
+
s.add_development_dependency("libxml-ruby", ["~> 1.1.4"])
|
9
|
+
s.add_development_dependency("nokogiri", ["~> 1.4.3"])
|
10
|
+
s.add_development_dependency("rake", ["~> 0.8.7"])
|
11
|
+
s.add_development_dependency("rspec", ["~> 1.3.0"])
|
12
|
+
s.name = "multi_xml"
|
13
|
+
s.version = MultiXml::VERSION
|
14
|
+
s.platform = Gem::Platform::RUBY
|
15
|
+
s.authors = ["Erik Michaels-Ober"]
|
16
|
+
s.email = ["sferik@gmail.com"]
|
17
|
+
s.homepage = "http://rubygems.org/gems/multi_xml"
|
18
|
+
s.summary = %q{A gem to provide swappable XML backends utilizing LibXML, Nokogiri, Hpricot, or REXML.}
|
19
|
+
s.description = s.summary
|
20
|
+
s.rubyforge_project = "multi_xml"
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
class MockDecoder
|
4
|
+
def self.parse(string)
|
5
|
+
'<tag>This is the contents</tag>'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "MultiXml" do
|
10
|
+
context 'engines' do
|
11
|
+
it 'should default to the best available gem' do
|
12
|
+
pending
|
13
|
+
require 'libxml'
|
14
|
+
MultiXml.engine.name.should == 'MultiXml::Engines::Libxml'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should be settable via a symbol' do
|
18
|
+
pending
|
19
|
+
MultiXml.engine = :libxml
|
20
|
+
MultiXml.engine.name.should == 'MultiXml::Engines::Libxml'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should be settable via a class' do
|
24
|
+
MultiXml.engine = MockDecoder
|
25
|
+
MultiXml.engine.name.should == 'MockDecoder'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
%w(libxml nokogiri hpricot rexml).each do |engine|
|
30
|
+
context engine do
|
31
|
+
before do
|
32
|
+
begin
|
33
|
+
MultiXml.engine = engine
|
34
|
+
rescue LoadError
|
35
|
+
pending "Engine #{engine} couldn't be loaded (not installed?)"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '.parse' do
|
40
|
+
it 'should properly parse some XML' do
|
41
|
+
MultiXml.parse('<tag>This is the contents</tag>').should == {'tag' => 'This is the contents'}
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should allow for symbolization of keys' do
|
45
|
+
MultiXml.parse('<tag>This is the contents</tag>', :symbolize_keys => true).should == {:tag => 'This is the contents'}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'multi_xml'
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
require 'rubygems'
|
7
|
+
begin
|
8
|
+
require 'bundler'
|
9
|
+
Bundler.setup
|
10
|
+
rescue LoadError
|
11
|
+
$stderr.puts "Bundler (or a dependency) not available."
|
12
|
+
end
|
13
|
+
|
14
|
+
Spec::Runner.configure do |config|
|
15
|
+
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: multi_xml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Erik Michaels-Ober
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-02 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: bundler
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 19
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
- 2
|
34
|
+
version: 1.0.2
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: hpricot
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 59
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 8
|
49
|
+
- 2
|
50
|
+
version: 0.8.2
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: libxml-ruby
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 27
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 1
|
65
|
+
- 4
|
66
|
+
version: 1.1.4
|
67
|
+
type: :development
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: nokogiri
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 1
|
78
|
+
segments:
|
79
|
+
- 1
|
80
|
+
- 4
|
81
|
+
- 3
|
82
|
+
version: 1.4.3
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: rake
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 49
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
- 8
|
97
|
+
- 7
|
98
|
+
version: 0.8.7
|
99
|
+
type: :development
|
100
|
+
version_requirements: *id005
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: rspec
|
103
|
+
prerelease: false
|
104
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 27
|
110
|
+
segments:
|
111
|
+
- 1
|
112
|
+
- 3
|
113
|
+
- 0
|
114
|
+
version: 1.3.0
|
115
|
+
type: :development
|
116
|
+
version_requirements: *id006
|
117
|
+
description: A gem to provide swappable XML backends utilizing LibXML, Nokogiri, Hpricot, or REXML.
|
118
|
+
email:
|
119
|
+
- sferik@gmail.com
|
120
|
+
executables: []
|
121
|
+
|
122
|
+
extensions: []
|
123
|
+
|
124
|
+
extra_rdoc_files: []
|
125
|
+
|
126
|
+
files:
|
127
|
+
- .gitignore
|
128
|
+
- Gemfile
|
129
|
+
- Gemfile.lock
|
130
|
+
- LICENSE
|
131
|
+
- README.rdoc
|
132
|
+
- Rakefile
|
133
|
+
- lib/multi_xml.rb
|
134
|
+
- lib/multi_xml/engines/rexml.rb
|
135
|
+
- lib/multi_xml/version.rb
|
136
|
+
- multi_xml.gemspec
|
137
|
+
- spec/multi_xml_spec.rb
|
138
|
+
- spec/spec.opts
|
139
|
+
- spec/spec_helper.rb
|
140
|
+
has_rdoc: true
|
141
|
+
homepage: http://rubygems.org/gems/multi_xml
|
142
|
+
licenses: []
|
143
|
+
|
144
|
+
post_install_message:
|
145
|
+
rdoc_options: []
|
146
|
+
|
147
|
+
require_paths:
|
148
|
+
- lib
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
hash: 3
|
155
|
+
segments:
|
156
|
+
- 0
|
157
|
+
version: "0"
|
158
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
hash: 3
|
164
|
+
segments:
|
165
|
+
- 0
|
166
|
+
version: "0"
|
167
|
+
requirements: []
|
168
|
+
|
169
|
+
rubyforge_project: multi_xml
|
170
|
+
rubygems_version: 1.3.7
|
171
|
+
signing_key:
|
172
|
+
specification_version: 3
|
173
|
+
summary: A gem to provide swappable XML backends utilizing LibXML, Nokogiri, Hpricot, or REXML.
|
174
|
+
test_files:
|
175
|
+
- spec/multi_xml_spec.rb
|
176
|
+
- spec/spec.opts
|
177
|
+
- spec/spec_helper.rb
|