roxo 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/roxo.rb +48 -57
- data/roxo.gemspec +1 -1
- metadata +2 -2
data/lib/roxo.rb
CHANGED
@@ -7,71 +7,62 @@ require 'libxml'
|
|
7
7
|
# z.bar.baz #=> "asdf"
|
8
8
|
|
9
9
|
# Ruby Objects as XML Objects
|
10
|
-
|
11
|
-
|
12
|
-
|
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)
|
10
|
+
class ROXO
|
11
|
+
instance_methods.each do |meth|
|
12
|
+
eval "undef #{meth}" unless [:__send__, :__id__, :object_id, :class].include?(meth.to_sym)
|
16
13
|
end
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
include Comparable
|
16
|
+
|
17
|
+
# Accessors and other one-liners
|
18
|
+
attr_reader :raw, :name, :value, :children
|
19
|
+
def __attributes; @attributes; end
|
20
|
+
def attributes; @attributes.keys; end
|
21
|
+
def terminal?; @children.size.zero?; end # A node is terminal if we can't descend any further
|
22
|
+
def has?(o); !! send(o); end # Boolean. Does this exist?
|
23
|
+
def [](o); @attributes[o.to_s]; end # Only lookup attributes
|
24
|
+
def to_s; @value; end
|
25
|
+
|
26
|
+
def initialize(xml)
|
27
|
+
unless xml.class == LibXML::XML::Parser
|
28
|
+
method = xml.respond_to?(:read) ? :read : :to_s
|
29
|
+
xml = ::LibXML::XML::Parser.string(xml.send(method))
|
30
|
+
end
|
26
31
|
|
27
|
-
|
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
|
32
|
+
@raw, @name, @attributes = xml, xml.name, xml.attributes.to_h
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
34
|
+
@children = xml.children.select(&:element?).group_by{|c|c.name.to_sym}
|
35
|
+
|
36
|
+
text_value = xml.children.select(&:text?).map(&:to_s).reject(&:empty?).join
|
37
|
+
cdata_value = xml.children.select(&:cdata?).map{|c|c.to_s.chomp(']]>').sub('<![CDATA[', '')}.join
|
38
|
+
@value = text_value.empty? ? cdata_value : text_value
|
39
|
+
end
|
52
40
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
return z unless (z = self.value <=> other.value ).zero?
|
57
|
-
return z unless (z = self.name <=> other.name ).zero?
|
41
|
+
def inspect
|
42
|
+
terminal? ? value.inspect : "#<ROXO(#{name}):0x#{object_id.to_s(16)}>"
|
43
|
+
end
|
58
44
|
|
59
|
-
|
60
|
-
|
45
|
+
def <=>(other)
|
46
|
+
return z unless (z = self.class <=> other.class ).zero?
|
47
|
+
return z unless (z = self.__attributes.sort <=> other.__attributes.sort).zero?
|
48
|
+
return z unless (z = self.value <=> other.value ).zero?
|
49
|
+
return z unless (z = self.name <=> other.name ).zero?
|
61
50
|
|
62
|
-
|
63
|
-
|
51
|
+
our_nodes = self.children.values.flatten.map{|n|self.class.new(n)}
|
52
|
+
their_nodes = other.children.values.flatten.map{|n|self.class.new(n)}
|
64
53
|
|
65
|
-
|
66
|
-
|
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
|
54
|
+
our_nodes.sort <=> their_nodes.sort
|
55
|
+
end
|
74
56
|
|
57
|
+
def method_missing(sym, *args)
|
58
|
+
if @children_by_name[sym]
|
59
|
+
return self.class.new(@children_by_name[sym].first)
|
60
|
+
elsif @attributes[sym.to_s]
|
61
|
+
return @attributes[sym.to_s]
|
62
|
+
elsif @children_by_name[sing = sym.to_s.singularize.to_sym]
|
63
|
+
return @children_by_name[sing].map{|e|self.class.new(e)}
|
64
|
+
end
|
75
65
|
end
|
76
|
-
|
66
|
+
|
77
67
|
end
|
68
|
+
|
data/roxo.gemspec
CHANGED