Module: Duxml::ElementGuts
- Includes:
- Duxml, LazyOx, Enumerable, Reportable
- Defined in:
- lib/duxml/doc/element.rb,
lib/duxml/doc/element.rb
Overview
contains actual methods of XML Element
Instance Attribute Summary
Attributes included from Reportable
Attributes included from Duxml
Attributes included from Saxer
Instance Method Summary collapse
-
#<<(obj) ⇒ Element
this override reports changes to history; NewText for Strings, Add for elements.
-
#[](index_or_attr) ⇒ Element, String
String if attribute value or text node; Element if XML node.
-
#[]=(attr_sym, val) ⇒ Element
Self.
-
#abstract? ⇒ Boolean
Whether or not this has been written to file.
-
#add(obj, index = -1)) ⇒ Element
this version of the method allows insertions between existing elements.
-
#dclone(source = self) ⇒ Element
Deep clone of source, including its attributes and recursively cloned children.
-
#delete(obj) ⇒ Element
(also: #remove)
TODO do we need this method to take Fixnum node index as well?.
-
#description ⇒ String
Self description.
-
#each(&block) ⇒ Object
traverse through just the children of this node.
-
#history ⇒ HistoryClass
History that is observing this element for changes.
-
#inspect ⇒ Object
#to_s.
-
#name_space ⇒ String
Namespace of element, derived from name e.g.
-
#sclone ⇒ Element
Shallow clone of this element, with all attributes and children only if none are Elements.
-
#set_doc!(_doc) ⇒ Element
Self.
-
#stub ⇒ Element
Copy of this Element but with no children.
-
#text? ⇒ true, false
True if all child nodes are text only; false if any child nodes are XML.
-
#to_s ⇒ String
XML string (overrides Ox’s to_s which just prints the object pointer).
-
#traverse(node = nil, &block) ⇒ Object
pre-order traverse through this node and all of its descendants.
Methods included from LazyOx
Methods included from Reportable
Methods included from Duxml
Methods included from Saxer
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Duxml::LazyOx
Instance Method Details
#<<(obj) ⇒ Element
this override reports changes to history; NewText for Strings, Add for elements
77 78 79 |
# File 'lib/duxml/doc/element.rb', line 77 def <<(obj) add(obj) end |
#[](index_or_attr) ⇒ Element, String
Returns string if attribute value or text node; Element if XML node.
114 115 116 |
# File 'lib/duxml/doc/element.rb', line 114 def [](index_or_attr) index_or_attr.is_a?(Fixnum) ? nodes[index_or_attr] : super(index_or_attr) end |
#[]=(attr_sym, val) ⇒ Element
Returns self.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/duxml/doc/element.rb', line 121 def []=(attr_sym, val) if attr_sym.is_a?(Fixnum) remove nodes[attr_sym] add(val, attr_sym) return self end attr = attr_sym.to_s raise "argument to [] must be a Symbol or a String." unless attr.is_a?(Symbol) or attr.is_a?(String) args = [attr] args << attributes[attr] if attributes[attr] super(attr, val) type = args.size == 1 ? :NewAttr : :ChangeAttr report(type, *args) self end |
#abstract? ⇒ Boolean
Returns whether or not this has been written to file.
57 58 59 |
# File 'lib/duxml/doc/element.rb', line 57 def abstract? line < 0 || column < 0 end |
#add(obj, index = -1)) ⇒ Element
this version of the method allows insertions between existing elements
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/duxml/doc/element.rb', line 87 def add(obj, index=-1) case when obj.is_a?(Array), obj.is_a?(NodeSet) obj.each_with_index do |e, i| add(e, index == -1 ? index : index+i) end when obj.is_a?(String) if obj[0] == '<' and obj[-1] == '>' and (s = Ox.parse(obj)) add dclone s else type = :NewText nodes.insert(index, obj) end else type = :Add nodes.insert(index, obj) if obj.count_observers < 1 && @observer_peers obj.add_observer(@observer_peers.first.first) end obj.set_doc! @doc end report(type, obj, index) self end |
#dclone(source = self) ⇒ Element
Returns deep clone of source, including its attributes and recursively cloned children.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/duxml/doc/element.rb', line 209 def dclone(source = self) input_stack = [] output_stack = [] traverse(source) do |node| if node.is_a?(String) output_stack.last << node next end copy = Element.new(node.name, node.attributes) if output_stack.empty? output_stack << copy input_stack << node else if input_stack.last.nodes.none? do |n| n === node end input_stack.pop output_stack.pop end output_stack.last << copy if node.nodes.any? output_stack << copy input_stack << node end end end output_stack.pop end |
#delete(obj) ⇒ Element Also known as: remove
TODO do we need this method to take Fixnum node index as well?
168 169 170 171 |
# File 'lib/duxml/doc/element.rb', line 168 def delete(obj) report(:Remove, @nodes.delete(obj)) obj end |
#description ⇒ String
Returns self description.
138 139 140 |
# File 'lib/duxml/doc/element.rb', line 138 def description "<#{name}>" end |
#each(&block) ⇒ Object
traverse through just the children of this node
196 197 198 |
# File 'lib/duxml/doc/element.rb', line 196 def each(&block) @nodes.each(&block) end |
#history ⇒ HistoryClass
Returns history that is observing this element for changes.
148 149 150 |
# File 'lib/duxml/doc/element.rb', line 148 def history @observer_peers.first.first if @observer_peers.respond_to?(:any?) and @observer_peers.any? and @observer_peers.first.any? end |
#inspect ⇒ Object
Returns #to_s.
161 162 163 |
# File 'lib/duxml/doc/element.rb', line 161 def inspect to_s end |
#name_space ⇒ String
Returns namespace of element, derived from name e.g. ‘<duxml:element>’ => ‘duxml’.
201 202 203 204 |
# File 'lib/duxml/doc/element.rb', line 201 def name_space return nil unless (i = name.index(':')) name[0..i-1] end |
#sclone ⇒ Element
Returns shallow clone of this element, with all attributes and children only if none are Elements.
240 241 242 243 244 |
# File 'lib/duxml/doc/element.rb', line 240 def sclone stub = Element.new(name, attributes) stub << nodes if text? stub end |
#set_doc!(_doc) ⇒ Element
Returns self.
63 64 65 66 67 68 69 70 |
# File 'lib/duxml/doc/element.rb', line 63 def set_doc!(_doc) @doc = _doc traverse do |node| next if node === self or node.is_a?(String) node.set_doc!(_doc) end self end |
#stub ⇒ Element
Returns copy of this Element but with no children.
143 144 145 |
# File 'lib/duxml/doc/element.rb', line 143 def stub Element.new(name, attributes) end |
#text? ⇒ true, false
Returns true if all child nodes are text only; false if any child nodes are XML.
247 248 249 |
# File 'lib/duxml/doc/element.rb', line 247 def text? nodes.all? do |node| node.is_a?(String) end end |
#to_s ⇒ String
Returns XML string (overrides Ox’s to_s which just prints the object pointer).
153 154 155 156 157 158 |
# File 'lib/duxml/doc/element.rb', line 153 def to_s s = %(<#{name}) attributes.each do |k,v| s << %( #{k.to_s}="#{v}") end return s+'/>' if nodes.empty? s << ">#{nodes.collect do |n| n.to_s end.join}</#{name}>" end |
#traverse(node = nil, &block) ⇒ Object
pre-order traverse through this node and all of its descendants
178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/duxml/doc/element.rb', line 178 def traverse(node=nil, &block) return self.to_enum unless block_given? node_stack = [node || self] until node_stack.empty? current = node_stack.shift if current yield current node_stack = node_stack.insert(0, *current.nodes) if current.respond_to?(:nodes) end end node || self if block_given? end |