jordi-xml_struct 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|