module RubyXL::OOXMLObjectInstanceMethods
def self.included(klass)
def self.included(klass) klass.extend RubyXL::OOXMLObjectClassMethods end
def ==(other)
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
def before_write_xml
along with option to terminate the actual write if +false+ is returned (for example, to avoid writing
Subclass provided filter to perform last-minute operations (cleanup, count, etc.) immediately prior to write,
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
def get_node_object(child_node_params)
def get_node_object(child_node_params) self.send(child_node_params[:accessor]) end
def index_in_collection
is expected to reside in the collection. If +nil+ is returned, then object is simply added
Prototype method. For sparse collections (+Rows+, +Cells+, etc.) must return index at which this object
def index_in_collection nil end
def init_child_nodes(params)
def init_child_nodes(params) obtain_class_variable(:@@ooxml_child_nodes).each_value { |v| initial_value = if params.has_key?(v[:accessor]) then params[v[:accessor]] elsif v[:is_array] then [] else nil end instance_variable_set("@#{v[:accessor]}", initial_value) } end
def initialize(params = {})
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
def obtain_class_variable(var_name, default = {})
def obtain_class_variable(var_name, default = {}) self.class.obtain_class_variable(var_name, default) end
def write_xml(xml = nil, node_name_override = nil)
obj.write_xml(seed_xml, 'overriden_element_name')
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)
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()
==== Examples
* +node_name_override+ - if present, is used instead of the default element name for this object provided by +define_element_name+
* +xml+ - Base Nokogiri::XML object used for building. If omitted, a blank document will be generated.
=== Parameters
can be used without additional +nil+ checking)
returns +false+, an empty string is returned (rather than +nil+, so Nokogiri::XML's << operator
generation, +before_write_xml()+ is called to perform last-minute cleanup and validation operations; if it
Recursively write the OOXML object and all its children out as Nokogiri::XML. Immediately before the actual
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