Class: Lutaml::Xml::Builder::Base
- Inherits:
-
Object
- Object
- Lutaml::Xml::Builder::Base
show all
- Defined in:
- lib/lutaml/xml/builder/base.rb
Overview
Base builder for XML construction using moxml. All adapter-specific builders inherit from this class.
The builder creates XML documents through moxml’s document model. Declaration, doctype, indentation, and line endings are handled by moxml — no manual string assembly.
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#add_cdata(element, value) ⇒ Object
-
#add_comment(element_or_text, text = nil) ⇒ Object
-
#add_processing_instruction(target, content) ⇒ Object
-
#add_text(element, text_content, cdata: false) ⇒ Object
-
#add_xml_fragment(element, content) ⇒ Object
-
#cdata(content) ⇒ Object
-
#create_and_add_element(element_name, prefix: (prefix_unset = true nil), attributes: {}, blank_xmlns: false) ⇒ Object
-
#current_element ⇒ Object
(also: #current_node)
-
#initialize(doc, context, options = {}) ⇒ Base
constructor
-
#method_missing(method_name, *args) ⇒ Object
-
#parent ⇒ Object
-
#respond_to_missing?(_method_name, _include_private = false) ⇒ Boolean
-
#text(content) ⇒ Object
-
#to_xml ⇒ Object
-
#xml ⇒ Object
Constructor Details
#initialize(doc, context, options = {}) ⇒ Base
Returns a new instance of Base.
78
79
80
81
82
83
84
|
# File 'lib/lutaml/xml/builder/base.rb', line 78
def initialize(doc, context, options = {})
@doc = doc
@context = context
@encoding = options[:encoding]
@current_stack = [doc]
@declaration_mode = :none
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args) ⇒ Object
182
183
184
185
|
# File 'lib/lutaml/xml/builder/base.rb', line 182
def method_missing(method_name, *args, &)
attrs = args.first.is_a?(Hash) ? args.first : {}
create_and_add_element(method_name.to_s, attributes: attrs, &)
end
|
Instance Attribute Details
#declaration_mode ⇒ Object
Returns the value of attribute declaration_mode.
76
77
78
|
# File 'lib/lutaml/xml/builder/base.rb', line 76
def declaration_mode
@declaration_mode
end
|
#doc ⇒ Object
Returns the value of attribute doc.
75
76
77
|
# File 'lib/lutaml/xml/builder/base.rb', line 75
def doc
@doc
end
|
#encoding ⇒ Object
Returns the value of attribute encoding.
76
77
78
|
# File 'lib/lutaml/xml/builder/base.rb', line 76
def encoding
@encoding
end
|
Class Method Details
.build(options = {}) {|instance| ... } ⇒ Object
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
# File 'lib/lutaml/xml/builder/base.rb', line 15
def self.build(options = {})
context = Moxml.new(moxml_backend)
if Lutaml::Model::RuntimeCompatibility.opal?
context.config.namespace_validation_mode = :lenient
end
encoding_value = options.delete(:encoding)
context.config.default_indent = options.delete(:indent) if options.key?(:indent)
context.config.default_line_ending = options.delete(:line_ending) if options.key?(:line_ending)
doc = context.create_document
doctype = options.delete(:doctype)
instance = new(doc, context, options)
instance.encoding = encoding_value if encoding_value
yield(instance) if block_given?
if doctype && doc.root
dt = doc.create_doctype(
doctype[:name],
doctype[:public_id],
doctype[:system_id],
)
doc.add_child(dt)
end
xml_decl = options.delete(:xml_declaration) || {}
include_decl = options.delete(:include_declaration)
force_decl = options.delete(:force_declaration)
if include_decl
version = xml_decl[:version] || "1.0"
encoding = xml_decl[:encoding]
encoding ||= "UTF-8" unless xml_decl[:had_declaration]
standalone = xml_decl[:standalone]
decl = doc.create_declaration(version, encoding, standalone)
doc.add_child(decl)
instance.declaration_mode = :default
elsif force_decl
decl_encoding = encoding_value || "UTF-8"
decl = doc.create_declaration("1.0", decl_encoding, nil)
doc.add_child(decl)
instance.declaration_mode = :default
else
instance.declaration_mode = :none
end
instance
end
|
.moxml_backend ⇒ Object
Override in subclass to set the moxml backend
71
72
73
|
# File 'lib/lutaml/xml/builder/base.rb', line 71
def self.moxml_backend
nil
end
|
Instance Method Details
#add_cdata(element, value) ⇒ Object
131
132
133
|
# File 'lib/lutaml/xml/builder/base.rb', line 131
def add_cdata(element, value)
resolve_target(element).add_child(@doc.create_cdata(value.to_s))
end
|
135
136
137
138
139
140
141
142
143
144
|
# File 'lib/lutaml/xml/builder/base.rb', line 135
def (element_or_text, text = nil)
if text.nil?
target = current_element
= element_or_text
else
target = resolve_target(element_or_text)
= text
end
target.add_child(@doc.(.to_s))
end
|
#add_processing_instruction(target, content) ⇒ Object
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
# File 'lib/lutaml/xml/builder/base.rb', line 146
def add_processing_instruction(target, content)
pi = @doc.create_processing_instruction(target.to_s, content.to_s)
if current_element.is_a?(Moxml::Document)
root_node = current_element.root
if root_node
root_node.add_previous_sibling(pi)
else
current_element.add_child(pi)
end
else
current_element.add_child(pi)
end
pi
end
|
#add_text(element, text_content, cdata: false) ⇒ Object
125
126
127
128
129
|
# File 'lib/lutaml/xml/builder/base.rb', line 125
def add_text(element, text_content, cdata: false)
return add_cdata(element, text_content) if cdata
resolve_target(element).add_child(@doc.create_text(text_content.to_s))
end
|
#add_xml_fragment(element, content) ⇒ Object
117
118
119
120
121
122
123
|
# File 'lib/lutaml/xml/builder/base.rb', line 117
def add_xml_fragment(element, content)
target = resolve_target(element)
parsed = @context.parse("<__root__>#{content}</__root__>")
parsed.root&.children&.each { |child| target.add_child(child) }
rescue Moxml::ParseError
target.add_child(@doc.create_text(content.to_s))
end
|
#cdata(content) ⇒ Object
165
166
167
|
# File 'lib/lutaml/xml/builder/base.rb', line 165
def cdata(content)
add_cdata(current_element, content)
end
|
#create_and_add_element(element_name, prefix: (prefix_unset = true
nil), attributes: {}, blank_xmlns: false) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/lutaml/xml/builder/base.rb', line 99
def create_and_add_element(
element_name,
prefix: (prefix_unset = true
nil),
attributes: {},
blank_xmlns: false
)
element_name = element_name.first if element_name.is_a?(Array)
new_el = @doc.create_element(element_name)
apply_attributes(new_el, attributes, blank_xmlns)
resolve_namespace(new_el, prefix, prefix_unset)
attach_to_parent(new_el, prefix, prefix_unset)
with_element_context(new_el) { yield(self) } if block_given?
new_el
end
|
#current_element ⇒ Object
Also known as:
current_node
86
87
88
|
# File 'lib/lutaml/xml/builder/base.rb', line 86
def current_element
@current_stack.last
end
|
#parent ⇒ Object
95
96
97
|
# File 'lib/lutaml/xml/builder/base.rb', line 95
def parent
current_element
end
|
#respond_to_missing?(_method_name, _include_private = false) ⇒ Boolean
187
188
189
|
# File 'lib/lutaml/xml/builder/base.rb', line 187
def respond_to_missing?(_method_name, _include_private = false)
true
end
|
#text(content) ⇒ Object
161
162
163
|
# File 'lib/lutaml/xml/builder/base.rb', line 161
def text(content)
add_text(current_element, content)
end
|
#to_xml ⇒ Object
169
170
171
172
173
174
175
176
177
178
179
180
|
# File 'lib/lutaml/xml/builder/base.rb', line 169
def to_xml
return "" unless @doc.root
result = if @declaration_mode == :none && !has_document_level_nodes?
@doc.root.to_xml(declaration: false, expand_empty: false)
else
@doc.to_xml(declaration: @declaration_mode == :default, expand_empty: false)
end
result = result.encode(encoding) if encoding && result.encoding.to_s != encoding
result
end
|
#xml ⇒ Object
91
92
93
|
# File 'lib/lutaml/xml/builder/base.rb', line 91
def xml
self
end
|