Module: RubyXL::OOXMLObjectInstanceMethods

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#local_namespacesObject

Returns the value of attribute local_namespaces.



215
216
217
# File 'lib/rubyXL/objects/ooxml_object.rb', line 215

def local_namespaces
  @local_namespaces
end

Class Method Details

.included(klass) ⇒ Object



217
218
219
# File 'lib/rubyXL/objects/ooxml_object.rb', line 217

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

Instance Method Details

#==(other) ⇒ Object



255
256
257
258
259
# File 'lib/rubyXL/objects/ooxml_object.rb', line 255

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).



355
356
357
358
359
360
361
362
# File 'lib/rubyXL/objects/ooxml_object.rb', line 355

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.



343
344
345
# File 'lib/rubyXL/objects/ooxml_object.rb', line 343

def index_in_collection
  nil
end

#initialize(params = nil) ⇒ Object



226
227
228
229
230
231
232
233
234
235
# File 'lib/rubyXL/objects/ooxml_object.rb', line 226

def initialize(params = nil)
  @local_namespaces = nil
  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.



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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/rubyXL/objects/ooxml_object.rb', line 275

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'

    if Nokogiri.jruby? then # Issue 188 workaround for JRuby
      seed_xml.to_java.strict_error_checking = false
    end

    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

  attrs = {}

  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)

  if @local_namespaces.nil? || @local_namespaces.empty? then # If no local namespaces provided in the original document,
    # use the defaults
    obtain_class_variable(:@@ooxml_namespaces).each_pair { |k, v| elem.add_namespace_definition(v, k) }
  else # otherwise preserve the original ones
    @local_namespaces.each { |ns| elem.add_namespace_definition(ns.prefix, ns.href) }
  end

  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 its members.
      node_obj.each { |item| elem << item.write_xml(xml, child_node_name) unless item.nil? }
    end
  }
  elem
end