Class: Xlsxrb::Ooxml::XmlBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/xlsxrb/ooxml/xml_builder.rb,
sig/generated/xlsxrb/ooxml/xml_builder.rbs

Overview

Streams well-formed XML to a writable IO without building a DOM.

Constant Summary collapse

XML_HEADER =

Returns:

  • (::String)
%(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n)
ESCAPE_MAP =

Returns:

  • (Object)
{
  "&" => "&amp;",
  "<" => "&lt;",
  ">" => "&gt;",
  '"' => "&quot;",
  "'" => "&apos;"
}.freeze
ESCAPE_RE =

Returns:

  • (::Regexp)
/[&<>"']/
EMPTY_HASH =

Returns:

  • (Object)
{}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(io) ⇒ XmlBuilder

Returns a new instance of XmlBuilder.

Parameters:

  • io (Object)


21
22
23
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 21

def initialize(io)
  @io = io
end

Instance Method Details

#close_tag(name) ⇒ Object

Parameters:

  • name (Object)

Returns:

  • (Object)


52
53
54
55
56
57
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 52

def close_tag(name)
  @io.write("</")
  @io.write(name)
  @io.write(">")
  self
end

#declarationObject

Returns:

  • (Object)


25
26
27
28
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 25

def declaration
  @io << XML_HEADER
  self
end

#empty_tag(name, attrs = EMPTY_HASH) ⇒ Object

Parameters:

  • name (Object)
  • attrs (Object) (defaults to: EMPTY_HASH)

Returns:

  • (Object)


59
60
61
62
63
64
65
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 59

def empty_tag(name, attrs = EMPTY_HASH)
  @io.write("<")
  @io.write(name)
  write_attrs(attrs) unless attrs.empty?
  @io.write("/>")
  self
end

#escape(value) ⇒ Object

Parameters:

  • value (Object)

Returns:

  • (Object)


115
116
117
118
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 115

def escape(value)
  str = value.to_s
  str.match?(ESCAPE_RE) ? str.gsub(ESCAPE_RE, ESCAPE_MAP) : str
end

#open_tag(name, attrs = EMPTY_HASH) ⇒ Object

Parameters:

  • name (Object)
  • attrs (Object) (defaults to: EMPTY_HASH)

Returns:

  • (Object)


44
45
46
47
48
49
50
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 44

def open_tag(name, attrs = EMPTY_HASH)
  @io.write("<")
  @io.write(name)
  write_attrs(attrs) unless attrs.empty?
  @io.write(">")
  self
end

#raw(xml_string) ⇒ Object

Write raw XML string (for unmapped_data restoration).

Parameters:

  • xml_string (Object)

Returns:

  • (Object)


73
74
75
76
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 73

def raw(xml_string)
  @io << xml_string
  self
end

#tag(name, attrs = EMPTY_HASH, &block) ⇒ void

This method returns an undefined value.

Opens a tag, yields for children, then closes the tag.

Parameters:

  • name (Object)
  • attrs (Object) (defaults to: EMPTY_HASH)


33
34
35
36
37
38
39
40
41
42
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 33

def tag(name, attrs = EMPTY_HASH, &block)
  if block
    open_tag(name, attrs)
    yield self
    close_tag(name)
  else
    empty_tag(name, attrs)
  end
  self
end

#text(content) ⇒ Object

Parameters:

  • content (Object)

Returns:

  • (Object)


67
68
69
70
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 67

def text(content)
  @io << escape(content.to_s)
  self
end

#to_sObject

Returns:

  • (Object)


97
98
99
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 97

def to_s
  @io.is_a?(StringIO) ? @io.string : @io.to_s
end

#write_attrs(attrs) ⇒ Object

Parameters:

  • attrs (Object)

Returns:

  • (Object)


103
104
105
106
107
108
109
110
111
112
113
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 103

def write_attrs(attrs)
  attrs.each do |k, v|
    next if v.nil?

    @io.write(" ")
    @io.write(k.to_s)
    @io.write('="')
    @io.write(escape(v))
    @io.write('"')
  end
end

#write_unmapped(node) ⇒ Object

Serialize an unmapped_data hash back to XML.

Parameters:

  • node (Object)

Returns:

  • (Object)


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/xlsxrb/ooxml/xml_builder.rb', line 79

def write_unmapped(node)
  return unless node.is_a?(Hash) && node[:tag]

  tag_name = node[:tag]
  attrs = node[:attrs] || {}
  children = node[:children] || []
  text_content = node[:text]

  if children.empty? && (text_content.nil? || text_content.empty?)
    empty_tag(tag_name, attrs)
  else
    open_tag(tag_name, attrs)
    text(text_content) if text_content && !text_content.empty?
    children.each { |child| write_unmapped(child) }
    close_tag(tag_name)
  end
end