roxo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/MIT-LICENSE +19 -0
  2. data/lib/roxo.rb +77 -0
  3. data/roxo.gemspec +23 -0
  4. metadata +89 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Burke Libbey <burke@burkelibbey.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/lib/roxo.rb ADDED
@@ -0,0 +1,77 @@
1
+ require 'rubygems'
2
+ require 'active_support/inflector'
3
+ require 'libxml'
4
+
5
+ # z = ROXO.new("<foo a='zxcv'><bar><baz>asdf</baz></bar></foo>")
6
+ # z.a #=> "zxcv"
7
+ # z.bar.baz #=> "asdf"
8
+
9
+ # Ruby Objects as XML Objects
10
+ module ROXO
11
+ # Can take a String of XML data, or anything that responds to
12
+ # either +read+ or +to_s+.
13
+ def self.new(duck)
14
+ method = duck.respond_to?(:read) ? :read : :to_s
15
+ Element.new(::LibXML::XML::Parser.string(duck.send(method)).parse.root)
16
+ end
17
+
18
+ private ##################################################################
19
+
20
+ class Element
21
+ instance_methods.each do |meth|
22
+ eval "undef #{meth}" unless [:__send__, :__id__, :object_id, :class].include?(meth.to_sym)
23
+ end
24
+
25
+ include Comparable
26
+
27
+ # Accessors and other one-liners
28
+ attr_reader :raw, :name, :value
29
+ def __attributes; @attributes; end
30
+ def __children; @children; end
31
+ def attributes; @attributes.keys; end
32
+ def children; @children_by_name.keys; end
33
+ def terminal?; @children.size.zero?; end # A node is terminal if we can't descend any further
34
+ def has?(o); !! send(o); end # Boolean. Does this exist?
35
+ def [](o); @attributes[o.to_s]; end # Only lookup attributes
36
+ def to_s; @value; end
37
+
38
+ def initialize(xml)
39
+ @raw, @name, @attributes = xml, xml.name, xml.attributes.to_h
40
+
41
+ @children = xml.children.select(&:element?)
42
+ @children_by_name = @children.group_by{|c|c.name.to_sym}
43
+
44
+ text_value = xml.children.select(&:text?).map(&:to_s).reject(&:empty?).join
45
+ cdata_value = xml.children.select(&:cdata?).map{|c|c.to_s.chomp(']]>').sub('<![CDATA[', '')}.join
46
+ @value = text_value.empty? ? cdata_value : text_value
47
+ end
48
+
49
+ def inspect
50
+ terminal? ? value.inspect : "#<ROXO::Element(#{name}):0x#{object_id.to_s(16)}>"
51
+ end
52
+
53
+ def <=>(other)
54
+ return z unless (z = self.class <=> other.class ).zero?
55
+ return z unless (z = self.__attributes.sort <=> other.__attributes.sort).zero?
56
+ return z unless (z = self.value <=> other.value ).zero?
57
+ return z unless (z = self.name <=> other.name ).zero?
58
+
59
+ our_nodes = self.__children.map{|n|self.class.new(n)}
60
+ their_nodes = other.__children.map{|n|self.class.new(n)}
61
+
62
+ our_nodes.sort <=> their_nodes.sort
63
+ end
64
+
65
+ def method_missing(sym, *args)
66
+ if @children_by_name[sym]
67
+ return self.class.new(@children_by_name[sym].first)
68
+ elsif @attributes[sym.to_s]
69
+ return @attributes[sym.to_s]
70
+ elsif @children_by_name[sing = sym.to_s.singularize.to_sym]
71
+ return @children_by_name[sing].map{|e|self.class.new(e)}
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
data/roxo.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = 'roxo'
3
+ gem.version = "0.0.1"
4
+
5
+ gem.author, gem.email = 'Burke Libbey', "burke@burkelibbey.org"
6
+
7
+ gem.summary = "A simpler way to interact with XML in Ruby"
8
+ gem.description = "ROXO is a simple library for dealing with small XML documents with a nice API."
9
+
10
+ gem.required_ruby_version = '>= 1.8.7'
11
+
12
+ gem.add_dependency("libxml-ruby")
13
+ gem.add_dependency("activesupport")
14
+
15
+ gem.has_rdoc = false
16
+
17
+ gem.files = %w[
18
+ MIT-LICENSE
19
+ lib
20
+ lib/roxo.rb
21
+ roxo.gemspec
22
+ ]
23
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roxo
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Burke Libbey
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-19 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: libxml-ruby
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: activesupport
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :runtime
43
+ version_requirements: *id002
44
+ description: ROXO is a simple library for dealing with small XML documents with a nice API.
45
+ email: burke@burkelibbey.org
46
+ executables: []
47
+
48
+ extensions: []
49
+
50
+ extra_rdoc_files: []
51
+
52
+ files:
53
+ - MIT-LICENSE
54
+ - lib/roxo.rb
55
+ - roxo.gemspec
56
+ has_rdoc: true
57
+ homepage:
58
+ licenses: []
59
+
60
+ post_install_message:
61
+ rdoc_options: []
62
+
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 1
71
+ - 8
72
+ - 7
73
+ version: 1.8.7
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.3.6
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: A simpler way to interact with XML in Ruby
88
+ test_files: []
89
+