jordi-xml_struct 0.1.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/MIT-LICENSE +19 -0
- data/README.markdown +34 -0
- data/Rakefile +36 -0
- data/WHATSNEW +3 -0
- data/lib/jordi-xml_struct.rb +1 -0
- data/lib/xml_struct.rb +147 -0
- data/test/samples/lorem.xml +63 -0
- data/test/test_helper.rb +37 -0
- data/test/xml_struct_test.rb +115 -0
- data/xml_struct.gemspec +38 -0
- metadata +73 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008 Jordi Bunster <jordi@bunster.org>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
Documentation pending. For now:
|
2
|
+
|
3
|
+
# Example usage:
|
4
|
+
|
5
|
+
<recipe name="bread" prep_time="5 mins" cook_time="3 hours">
|
6
|
+
<title>Basic bread</title>
|
7
|
+
<ingredient amount="8" unit="dL">Flour</ingredient>
|
8
|
+
<ingredient amount="10" unit="grams">Yeast</ingredient>
|
9
|
+
<ingredient amount="4" unit="dL" state="warm">Water</ingredient>
|
10
|
+
<ingredient amount="1" unit="teaspoon">Salt</ingredient>
|
11
|
+
<instructions easy="yes" hard="false">
|
12
|
+
<step>Mix all ingredients together.</step>
|
13
|
+
<step>Knead thoroughly.</step>
|
14
|
+
<step>Cover with a cloth, and leave for one hour in warm room.</step>
|
15
|
+
<step>Knead again.</step>
|
16
|
+
<step>Place in a bread baking tin.</step>
|
17
|
+
<step>Cover with a cloth, and leave for one hour in warm room.</step>
|
18
|
+
<step>Bake in the oven at 180(degrees)C for 30 minutes.</step>
|
19
|
+
</instructions>
|
20
|
+
</recipe>
|
21
|
+
|
22
|
+
recipe = XMLStruct.new recipe_xml_shown_above
|
23
|
+
|
24
|
+
recipe.name => "bread"
|
25
|
+
recipe.title == "Basic bread" => true
|
26
|
+
|
27
|
+
recipe.ingredients.is_a?(Array) => true
|
28
|
+
recipe.ingredients.first.amount => 8
|
29
|
+
|
30
|
+
recipe.instructions.easy? => true
|
31
|
+
|
32
|
+
recipe.instructions.first.upcase => "MIX ALL INGREDIENTS TOGETHER."
|
33
|
+
recipe.instructions.steps.size => 7
|
34
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Run the unit tests.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'XMLStruct'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include 'README.markdown'
|
21
|
+
rdoc.rdoc_files.include 'lib/**/*.rb'
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Measures test coverage using rcov'
|
25
|
+
task :rcov do
|
26
|
+
rm_f 'coverage'
|
27
|
+
rm_f 'coverage.data'
|
28
|
+
|
29
|
+
rcov = %{ rcov --aggregate coverage.data --text-summary
|
30
|
+
--include lib
|
31
|
+
--exclude /Library/Ruby
|
32
|
+
}.strip!.gsub! /\s+/, ' '
|
33
|
+
|
34
|
+
system("#{rcov} --html #{Dir.glob('test/**/*_test.rb').join(' ')}")
|
35
|
+
system('open coverage/index.html') if PLATFORM['darwin']
|
36
|
+
end
|
data/WHATSNEW
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'xml_struct'
|
data/lib/xml_struct.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'activesupport'
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
class XMLStruct
|
6
|
+
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
# Returns an XMLStruct object
|
10
|
+
def self.new(duck)
|
11
|
+
duck.is_a?(REXML::Element) ? super : new(REXML::Document.new(duck).root)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Takes any REXML::Element object, and converts it recursively into
|
15
|
+
# the corresponding tree of XMLStruct objects
|
16
|
+
def initialize(raw)
|
17
|
+
@attributes, @children, @raw = {}, {}, raw
|
18
|
+
@value = __get_value_from_raw_element @raw
|
19
|
+
|
20
|
+
@raw.each_element { |el| __set_child el.name, self.class.new(el) }
|
21
|
+
@raw.attributes.each { |n, v| __set_attribute n, v }
|
22
|
+
end
|
23
|
+
|
24
|
+
# An XMLStruct is blank when it has a blank value, no child elements,
|
25
|
+
# and no attributes. For example:
|
26
|
+
#
|
27
|
+
# <blank_element></blank_element>
|
28
|
+
def blank?
|
29
|
+
@value.blank? && @children.blank? && @attributes.blank?
|
30
|
+
end
|
31
|
+
|
32
|
+
# XMLStruct objects are compared according to their values
|
33
|
+
def <=>(other)
|
34
|
+
@value <=> other
|
35
|
+
end
|
36
|
+
|
37
|
+
# Array-notation access to elements and attributes. It comes handy when
|
38
|
+
# the element or attribute you need to reach is not reachable via dot
|
39
|
+
# notation (because it's not a valid method name, or because the method
|
40
|
+
# exists, such as 'id' or 'class').
|
41
|
+
#
|
42
|
+
# It also supports hash keys, which are useful to reach attributes named
|
43
|
+
# the same as elements in the same level (which are otherwise prioritized)
|
44
|
+
#
|
45
|
+
# All of this is a lot easier to exampling by example:
|
46
|
+
#
|
47
|
+
# <article id="main_article" author="j-random">
|
48
|
+
# <author>J. Random Hacker</author>
|
49
|
+
# </article>
|
50
|
+
#
|
51
|
+
# article.id => 9314390 # Object#id gets called
|
52
|
+
# article[:id] => "main_article" # id attribute
|
53
|
+
# article[:author] => <XMLStruct ...> # <author> element
|
54
|
+
# article[:attr => 'author'] => "j-random" # author attribute
|
55
|
+
#
|
56
|
+
# Valid keys for the hash notation in the example above are :attr,
|
57
|
+
# :attribute, :child, and :element.
|
58
|
+
def [](name)
|
59
|
+
unless name.is_a? Hash
|
60
|
+
return @children[name.to_sym] if @children[name.to_sym]
|
61
|
+
return @attributes[name.to_sym] if @attributes[name.to_sym]
|
62
|
+
end
|
63
|
+
|
64
|
+
raise 'one and only one key allowed' if name.size != 1
|
65
|
+
|
66
|
+
case (param = name.keys.first.to_sym)
|
67
|
+
when :element : @children[name.values.first.to_sym]
|
68
|
+
when :child : @children[name.values.first.to_sym]
|
69
|
+
when :attr : @attributes[name.values.first.to_sym]
|
70
|
+
when :attribute : @attributes[name.values.first.to_sym]
|
71
|
+
else raise %{ Invalid key :#{param.to_s}.
|
72
|
+
Use one of :element, :child, :attr, or :attribute }.squish!
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def method_missing(method, *args, &block) # :nodoc:
|
77
|
+
|
78
|
+
if method.to_s.match(/\?$/) && args.empty? && block.nil?
|
79
|
+
boolish = send(method.to_s.chomp('?').to_sym).to_s
|
80
|
+
|
81
|
+
%w[ true yes t y ].include? boolish.downcase
|
82
|
+
|
83
|
+
elsif @value.blank? && (@children.size == 1) &&
|
84
|
+
(single_child = @children.values.first).respond_to?(method)
|
85
|
+
|
86
|
+
single_child.send method, *args, &block
|
87
|
+
else
|
88
|
+
@value.send method, *args, &block
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def inspect # :nodoc:
|
93
|
+
%{ #<#{self.class.to_s} value=#{@value.inspect} (#{@value.class.to_s})
|
94
|
+
attributes=[#{@attributes.keys.map(&:to_s).join(', ') }]
|
95
|
+
children=[#{@children.keys.map(&:to_s).join(', ') }]> }.squish
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def __set_child(name, element) # :nodoc:
|
101
|
+
key = name.to_sym
|
102
|
+
|
103
|
+
@children[key] = if @children[key]
|
104
|
+
|
105
|
+
unless respond_to?((plural_key = key.to_s.pluralize).to_sym)
|
106
|
+
instance_eval %{ def #{plural_key}; @children[:#{key.to_s}]; end }
|
107
|
+
end
|
108
|
+
|
109
|
+
@children[key] = [ @children[key] ] unless @children[key].is_a? Array
|
110
|
+
@children[key] << element
|
111
|
+
else
|
112
|
+
unless respond_to? key
|
113
|
+
instance_eval %{ def #{key.to_s}; @children[:#{key.to_s}]; end }
|
114
|
+
end
|
115
|
+
|
116
|
+
element
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def __set_attribute(name, attribute) # :nodoc:
|
121
|
+
obj = __get_object_from_string(attribute)
|
122
|
+
@attributes[(key = name.to_sym)] = obj.is_a?(String) ? obj.squish : obj
|
123
|
+
|
124
|
+
unless respond_to? key
|
125
|
+
instance_eval %{ def #{key.to_s}; @attributes[:#{key.to_s}]; end }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def __get_value_from_raw_element(raw) # :nodoc:
|
130
|
+
str = case
|
131
|
+
when raw.has_text? && !raw.text.blank? : raw.text
|
132
|
+
else (raw.cdatas.first.to_s rescue '')
|
133
|
+
end
|
134
|
+
|
135
|
+
__get_object_from_string str
|
136
|
+
end
|
137
|
+
|
138
|
+
def __get_object_from_string(str) # :nodoc:
|
139
|
+
case
|
140
|
+
when str.blank? : nil
|
141
|
+
when str.match(/[a-zA-Z]/) : str
|
142
|
+
when str.match(/^[+-]?\d+$/) : str.to_i
|
143
|
+
when str.match(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/) : str.to_f
|
144
|
+
else str
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<!-- Invalid method name test -->
|
2
|
+
<lorem id="root" name="ipsum dolor sit amet" _tempor="incididunt">
|
3
|
+
|
4
|
+
<_minim>veniam</_minim> <!-- Invalid method name test -->
|
5
|
+
|
6
|
+
<!-- unambiguous element/attribute access test -->
|
7
|
+
<sed do="eiusmod attributus">
|
8
|
+
<do>eiusmod elementus</do>
|
9
|
+
</sed>
|
10
|
+
|
11
|
+
<!-- Blank test -->
|
12
|
+
<ipsum></ipsum>
|
13
|
+
<dolor foo="bar"></dolor>
|
14
|
+
<sit><amet></amet></sit>
|
15
|
+
<ut>quis</ut>
|
16
|
+
|
17
|
+
<!-- To test the array folding feature, as well as the pluralization.
|
18
|
+
The attributes help test float, integer, and boolean recognition,
|
19
|
+
as well as method name clashing behaviour (id) -->
|
20
|
+
<consectetur id="1" capacity="2.13" enabled="yes" />
|
21
|
+
<consectetur id="2" capacity="-1.9" enabled="No" />
|
22
|
+
<consectetur id="3" capacity="13.0" enabled="True" />
|
23
|
+
<consectetur id="4" capacity="0.00" enabled="false" />
|
24
|
+
|
25
|
+
<!-- Test boolean recognition -->
|
26
|
+
<brutus>true</brutus>
|
27
|
+
|
28
|
+
<consecteturs> <!-- To test that we can still reach this, even though
|
29
|
+
the array of singular ones above will trap the call
|
30
|
+
to this when using dot notation -->
|
31
|
+
<culpa>officia</culpa>
|
32
|
+
</consecteturs>
|
33
|
+
|
34
|
+
<cupidatats> <!-- Test for the empty element == single array child
|
35
|
+
scenario, as well as date recognition -->
|
36
|
+
<cupidatat activated_at="2903-02-12">Aliqua</cupidatat>
|
37
|
+
<cupidatat activated_at="2903-02-13">Occaecat</cupidatat>
|
38
|
+
<cupidatat activated_at="2904-10-18">Cupidatat</cupidatat>
|
39
|
+
<cupidatat activated_at="2905-03-21">Mollit</cupidatat>
|
40
|
+
</cupidatats>
|
41
|
+
|
42
|
+
<!-- Non-empty element, should not be array proxy -->
|
43
|
+
<voluptate>
|
44
|
+
velit
|
45
|
+
<esse>cillum</esse>
|
46
|
+
<esse>cillum dolore</esse>
|
47
|
+
</voluptate>
|
48
|
+
|
49
|
+
<!-- Test for both text value and CDATA value -->
|
50
|
+
<ullamco>Laboris<![CDATA[nisi]]></ullamco>
|
51
|
+
|
52
|
+
<!-- Test for multiple CDATA values -->
|
53
|
+
<deserunt><![CDATA[mollit]]><![CDATA[anim]]></deserunt>
|
54
|
+
|
55
|
+
<!-- Test for whitespace preservation / squishing -->
|
56
|
+
<irure metadata="
|
57
|
+
dolor ">
|
58
|
+
reprehenderit </irure>
|
59
|
+
|
60
|
+
<!-- CDATA whitespace preservation test -->
|
61
|
+
<![CDATA[ foo
|
62
|
+
]]>
|
63
|
+
</lorem>
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'redgreen'
|
6
|
+
rescue LoadError
|
7
|
+
puts "Install the 'redgreen' gem to get color output"
|
8
|
+
end
|
9
|
+
|
10
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'xml_struct')
|
11
|
+
|
12
|
+
def xml_file(name_symbol)
|
13
|
+
File.open File.join(File.dirname(__FILE__), 'samples',
|
14
|
+
"#{name_symbol.to_s}.xml")
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'digest/md5'
|
18
|
+
{ :lorem => '6dc88e269000db3be599fca3367e2aa5' }.each do |file_key, md5|
|
19
|
+
|
20
|
+
unless Digest::MD5.hexdigest(xml_file(file_key).read) == md5
|
21
|
+
raise "Sample test file #{file_key.to_s}.xml doesn't match expected MD5"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Test::Unit::TestCase
|
26
|
+
def self.should(do_stuff_that_is_true, &block)
|
27
|
+
|
28
|
+
object = to_s.split('Test').first
|
29
|
+
method = "test that #{object} should #{do_stuff_that_is_true}"
|
30
|
+
|
31
|
+
define_method(method.intern) { assert block.bind(self).call }
|
32
|
+
end
|
33
|
+
|
34
|
+
def debug
|
35
|
+
require 'ruby-debug'; debugger
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class XMLStructTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include RubyProf::Test if defined? RubyProf::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@lorem = XMLStruct.new xml_file(:lorem)
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'be an XMLStruct' do
|
12
|
+
@lorem.is_a? XMLStruct
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'be blank if devoid of children, attributes and value' do
|
16
|
+
@lorem.ipsum.blank?
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'not be blank when value, children, or attributes are present' do
|
20
|
+
[ @lorem.dolor, @lorem.sit, @lorem.ut ].all? { |xr| not xr.blank? }
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'allow access to attributes named like invalid methods' do
|
24
|
+
@lorem['_tempor'] == 'incididunt'
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'allow access to elements named like invalid methods' do
|
28
|
+
@lorem['_minim'] == 'veniam'
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'provide unambiguous access to elements named like attributes' do
|
32
|
+
@lorem.sed[:element => 'do'] == 'eiusmod elementus'
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'provide unambiguous access to attributes named like elements' do
|
36
|
+
@lorem.sed[:attribute => 'do'] == 'eiusmod attributus'
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'return elements first when using dot notation' do
|
40
|
+
@lorem.sed.do == @lorem.sed[:element => 'do']
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'return elements first when using array notation and string key' do
|
44
|
+
@lorem.sed['do'] == @lorem.sed[:element => 'do']
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'return elements first when using array notation and symbol key' do
|
48
|
+
@lorem.sed[:do] == @lorem.sed[:element => 'do']
|
49
|
+
end
|
50
|
+
|
51
|
+
should 'raise exception when unkown keys are used in hash-in-array mode' do
|
52
|
+
(@lorem[:foo => 'bar']; false) rescue true
|
53
|
+
end
|
54
|
+
|
55
|
+
should 'group multiple parallel namesake elements in arrays' do
|
56
|
+
@lorem.consectetur.is_a? Array
|
57
|
+
end
|
58
|
+
|
59
|
+
should 'make auto-grouped arrays accessible by their plural form' do
|
60
|
+
@lorem.consecteturs.equal? @lorem.consectetur
|
61
|
+
end
|
62
|
+
|
63
|
+
should 'allow explicit access to elements named like plural arrays' do
|
64
|
+
not @lorem.consecteturs.equal? @lorem[:element => 'consecteturs']
|
65
|
+
end
|
66
|
+
|
67
|
+
should 'convert integer-looking attribute strings to integers' do
|
68
|
+
@lorem.consecteturs.all? { |c| c[:attr => 'id'].is_a? Numeric }
|
69
|
+
end
|
70
|
+
|
71
|
+
should 'convert float-looking attribute strings to floats' do
|
72
|
+
@lorem.consecteturs.all? { |c| c.capacity.is_a? Float }
|
73
|
+
end
|
74
|
+
|
75
|
+
should 'convert bool-looking attribute strings to bools when asked' do
|
76
|
+
@lorem.consecteturs.all? { |c| c.enabled?.equal? !!(c.enabled?) }
|
77
|
+
end
|
78
|
+
|
79
|
+
should 'convert to bool correctly when asked' do
|
80
|
+
@lorem.consecteturs.first.enabled? == true &&
|
81
|
+
@lorem.consecteturs.last.enabled? == false
|
82
|
+
end
|
83
|
+
|
84
|
+
should 'pass forth methods to single array child when empty valued' do
|
85
|
+
@lorem.cupidatats.slice(0).equal? @lorem.cupidatats.cupidatat.slice(0)
|
86
|
+
end
|
87
|
+
|
88
|
+
should 'not pass methods to single array child if not empty valued' do
|
89
|
+
not @lorem.voluptate.slice(0).equal? @lorem.voluptate.esse.slice(0)
|
90
|
+
end
|
91
|
+
|
92
|
+
should 'be valued as its text when text first and CDATA exist' do
|
93
|
+
@lorem.ullamco == 'Laboris'
|
94
|
+
end
|
95
|
+
|
96
|
+
should 'have the value of its first CDATA when multiple exist' do
|
97
|
+
@lorem.deserunt == 'mollit'
|
98
|
+
end
|
99
|
+
|
100
|
+
should 'squish whitespace in string attribute values' do
|
101
|
+
@lorem.irure.metadata == 'dolor'
|
102
|
+
end
|
103
|
+
|
104
|
+
should 'not squish whitespace in string element values' do
|
105
|
+
@lorem.irure == " \n\t\t\treprehenderit "
|
106
|
+
end
|
107
|
+
|
108
|
+
should 'not squish whitespace in CDATA values' do
|
109
|
+
@lorem == "\t foo\n"
|
110
|
+
end
|
111
|
+
|
112
|
+
should 'have a working inspect function' do
|
113
|
+
(@lorem.inspect.to_s.is_a? String; true) rescue false
|
114
|
+
end
|
115
|
+
end
|
data/xml_struct.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'xml_struct'
|
3
|
+
s.version = '0.1.1'
|
4
|
+
s.date = '2008-10-09'
|
5
|
+
|
6
|
+
s.author = 'Jordi Bunster'
|
7
|
+
s.email = 'jordi@bunster.org'
|
8
|
+
s.homepage = 'http://github.com/jordi/xml_struct'
|
9
|
+
|
10
|
+
s.add_dependency 'activesupport', '>= 2.1.1'
|
11
|
+
|
12
|
+
s.summary = "The Rubyista's way to do quick XML sit-ups"
|
13
|
+
s.description = %{ This is a library for reading (not writing) XML. It is
|
14
|
+
particularly suited for cases where one is dealing with
|
15
|
+
small documents of a known structure.
|
16
|
+
|
17
|
+
It is slow and not devoid of caveats, but has a very
|
18
|
+
pleasant, Ruby-like syntax. }.strip!.gsub! /\s+/, ' '
|
19
|
+
|
20
|
+
s.test_files = %w[ test
|
21
|
+
test/samples
|
22
|
+
test/samples/lorem.xml
|
23
|
+
test/test_helper.rb
|
24
|
+
test/xml_struct_test.rb ]
|
25
|
+
|
26
|
+
s.files = %w[ MIT-LICENSE
|
27
|
+
README.markdown
|
28
|
+
Rakefile
|
29
|
+
WHATSNEW
|
30
|
+
lib
|
31
|
+
lib/jordi-xml_struct.rb
|
32
|
+
lib/xml_struct.rb
|
33
|
+
xml_struct.gemspec ]
|
34
|
+
|
35
|
+
s.has_rdoc = true
|
36
|
+
s.extra_rdoc_files = %w[ README.markdown ]
|
37
|
+
s.rdoc_options = %w[ --main README.markdown ]
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jordi-xml_struct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jordi Bunster
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-10-09 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.1.1
|
23
|
+
version:
|
24
|
+
description: This is a library for reading (not writing) XML. It is particularly suited for cases where one is dealing with small documents of a known structure. It is slow and not devoid of caveats, but has a very pleasant, Ruby-like syntax.
|
25
|
+
email: jordi@bunster.org
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README.markdown
|
32
|
+
files:
|
33
|
+
- MIT-LICENSE
|
34
|
+
- README.markdown
|
35
|
+
- Rakefile
|
36
|
+
- WHATSNEW
|
37
|
+
- lib
|
38
|
+
- lib/jordi-xml_struct.rb
|
39
|
+
- lib/xml_struct.rb
|
40
|
+
- xml_struct.gemspec
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/jordi/xml_struct
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --main
|
46
|
+
- README.markdown
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.2.0
|
65
|
+
signing_key:
|
66
|
+
specification_version: 2
|
67
|
+
summary: The Rubyista's way to do quick XML sit-ups
|
68
|
+
test_files:
|
69
|
+
- test
|
70
|
+
- test/samples
|
71
|
+
- test/samples/lorem.xml
|
72
|
+
- test/test_helper.rb
|
73
|
+
- test/xml_struct_test.rb
|