Module: RubyXL::OOXMLObjectInstanceMethods

Included in:
OOXMLContainerObject, OOXMLObject
Defined in:
lib/rubyXL/objects/ooxml_object.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(klass) ⇒ Object


209
210
211
# File 'lib/rubyXL/objects/ooxml_object.rb', line 209

def self.included(klass)
  klass.extend RubyXL::OOXMLObjectClassMethods
end

Instance Method Details

#==(other) ⇒ Object


240
241
242
243
244
# File 'lib/rubyXL/objects/ooxml_object.rb', line 240

def ==(other)
  other.is_a?(self.class) &&
    obtain_class_variable(:@@ooxml_attributes).all? { |k, v| self.send(v[:accessor]) == other.send(v[:accessor]) } &&
    obtain_class_variable(:@@ooxml_child_nodes).all? { |k, v| self.send(v[:accessor]) == other.send(v[:accessor]) }
end

#before_write_xmlObject

Subclass provided filter to perform last-minute operations (cleanup, count, etc.) immediately prior to write, along with option to terminate the actual write if false is returned (for example, to avoid writing the collection's root node if the collection is empty).


330
331
332
333
334
335
336
337
# File 'lib/rubyXL/objects/ooxml_object.rb', line 330

def before_write_xml
  #TODO# This will go away once containers are fully implemented.
  child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
  child_nodes.each_pair { |child_node_name, child_node_params|
    self.count = self.send(child_node_params[:accessor]).size if child_node_params[:is_array] == :with_count
  }
  true
end

#index_in_collectionObject

Prototype method. For sparse collections (Rows, Cells, etc.) must return index at which this object is expected to reside in the collection. If nil is returned, then object is simply added to the end of the collection.


318
319
320
# File 'lib/rubyXL/objects/ooxml_object.rb', line 318

def index_in_collection
  nil
end

#initialize(params = {}) ⇒ Object


218
219
220
221
222
223
224
# File 'lib/rubyXL/objects/ooxml_object.rb', line 218

def initialize(params = {})
  obtain_class_variable(:@@ooxml_attributes).each_value { |v|
    instance_variable_set("@#{v[:accessor]}", params[v[:accessor]]) unless v[:computed]
  }

  init_child_nodes(params)
end

#write_xml(xml = nil, node_name_override = nil) ⇒ Object

Recursively write the OOXML object and all its children out as Nokogiri::XML. Immediately before the actual generation, before_write_xml() is called to perform last-minute cleanup and validation operations; if it returns false, an empty string is returned (rather than nil, so Nokogiri::XML's << operator can be used without additional nil checking)

Parameters

  • xml - Base Nokogiri::XML object used for building. If omitted, a blank document will be generated.

  • node_name_override - if present, is used instead of the default element name for this object provided by define_element_name

Examples

obj.write_xml()

Creates a new empty Nokogiri::XML, populates it with the OOXML structure as described in the respective definition, and returns the resulting Nokogiri::XML object.

obj.write_xml(seed_xml)

Using the passed-in Nokogiri xml object, creates a new element corresponding to obj according to its definition, along with all its properties and children, and returns the newly created element.

obj.write_xml(seed_xml, 'overriden_element_name')

Same as above, but uses the passed-in node_name_override as the new element name, instead of its default name set by define_element_name.


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/rubyXL/objects/ooxml_object.rb', line 260

def write_xml(xml = nil, node_name_override = nil)
  if xml.nil? then
    seed_xml = Nokogiri::XML('<?xml version = "1.0" standalone ="yes"?>')
    seed_xml.encoding = 'UTF-8'
    result = self.write_xml(seed_xml)
    return result if result == ''
    seed_xml << result
    return seed_xml.to_xml({ :indent => 0, :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML })
  end

  return '' unless before_write_xml

  # Populate namespaces, if any
  attrs = {}
  obtain_class_variable(:@@ooxml_namespaces).each_pair { |k, v| attrs[v.empty? ? 'xmlns' : "xmlns:#{v}"] = k }

  obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v|
    val = self.send(v[:accessor])

    if val.nil? then
      next unless v[:required]
      val = v[:default]
    end

    val = val &&
            case v[:attr_type]
            when :bool   then val ? '1' : '0'
            when :double then val.to_s.gsub(/\.0*\Z/, '') # Trim trailing zeroes
            else val
            end

    attrs[k] = val
  }

  element_text = attrs.delete('_')
  elem = xml.create_element(node_name_override || obtain_class_variable(:@@ooxml_tag_name), attrs, element_text)

  child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
  child_nodes.each_pair { |child_node_name, child_node_params|
    node_obj = get_node_object(child_node_params)
    next if node_obj.nil?

    if node_obj.respond_to?(:write_xml) && !node_obj.equal?(self) then
      # If child node is either +OOXMLObject+, or +OOXMLContainerObject+ on its first (envelope) pass,
      # serialize that object.
      elem << node_obj.write_xml(xml, child_node_name)
    else
      # If child node is either vanilla +Array+, or +OOXMLContainerObject+ on its seconds (content) pass,
      # serialize write its members.
      node_obj.each { |item| elem << item.write_xml(xml, child_node_name) unless item.nil? }
    end
  }
  elem
end