Method: RubyXL::OOXMLObjectInstanceMethods#write_xml

Defined in:
lib/rubyXL/objects/ooxml_object.rb

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

[View source]

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
339
340
# File 'lib/rubyXL/objects/ooxml_object.rb', line 278

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)

  # First, populate namespaces from the original document
  @local_namespaces&.each_pair { |href, prefix| elem.add_namespace_definition(prefix, href) }

  # Then, add defaults. Note that if some namespace prefix was already set, Nokogiri will NOT change that namespace.
  obtain_class_variable(:@@ooxml_namespaces).each_pair { |href, prefix| elem.add_namespace_definition(prefix, href) }

  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