Class: Tilia::Xml::Writer
- Inherits:
-
Object
- Object
- Tilia::Xml::Writer
- Includes:
- ContextStackTrait
- Defined in:
- lib/tilia/xml/writer.rb
Overview
The XML Writer class.
This class works exactly as PHP’s built-in XMLWriter, with a few additions.
Namespaces can be registered beforehand, globally. When the first element is written, namespaces will automatically be declared.
The write_attribute, startElement and write_element can now take a clark-notation element name (example: http://www.w3.org/2005/Atomlink).
If, when writing the namespace is a known one a prefix will automatically be selected, otherwise a random prefix will be generated.
Instead of standard string values, the writer can take Element classes (as defined by this library) to delegate the serialization.
The write() method can take array structures to quickly write out simple xml trees.
Instance Attribute Summary
Attributes included from ContextStackTrait
#class_map, #context_uri, #element_map, #namespace_map
Instance Method Summary collapse
-
#initialize ⇒ Writer
constructor
Initializes the instance variables.
-
#method_missing(name, *args) ⇒ Object
Delegates missing methods to XML::Writer instance.
-
#open_memory ⇒ void
Fakes the php function open_memory.
-
#output_memory ⇒ String
Fakes the php function output_memory.
-
#start_element(name) ⇒ Boolean
Starts an element.
-
#write(value) ⇒ void
Writes a value to the output stream.
-
#write_attribute(name, value) ⇒ Boolean
Writes a new attribute.
-
#write_attributes(attributes) ⇒ void
Writes a list of attributes.
-
#write_element(name, content = nil) ⇒ Boolean
Write a full element tag and it’s contents.
Methods included from ContextStackTrait
Constructor Details
#initialize ⇒ Writer
Initializes the instance variables
184 185 186 187 188 189 |
# File 'lib/tilia/xml/writer.rb', line 184 def initialize @adhoc_namespaces = {} @namespaces_written = false super end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
Delegates missing methods to XML::Writer instance
210 211 212 |
# File 'lib/tilia/xml/writer.rb', line 210 def method_missing(name, *args) @writer.send(name, *args) end |
Instance Method Details
#open_memory ⇒ void
This method returns an undefined value.
Fakes the php function open_memory
Initilizes the LibXML Writer
196 197 198 199 200 |
# File 'lib/tilia/xml/writer.rb', line 196 def open_memory raise 'XML document already created' if @writer @writer = ::LibXML::XML::Writer.string end |
#output_memory ⇒ String
Fakes the php function output_memory
205 206 207 |
# File 'lib/tilia/xml/writer.rb', line 205 def output_memory @writer.result end |
#start_element(name) ⇒ Boolean
Starts an element.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/tilia/xml/writer.rb', line 73 def start_element(name) if name[0] == '{' (namespace, local_name) = Service.parse_clark_notation(name) if @namespace_map.key?(namespace) tmp_ns = @namespace_map[namespace] tmp_ns = nil if tmp_ns.blank? result = start_element_ns(tmp_ns, local_name, nil) elsif namespace.blank? # An empty namespace means it's the global namespace. This is # allowed, but it mustn't get a prefix. result = start_element(local_name) write_attribute('xmlns', '') else unless @adhoc_namespaces.key?(namespace) @adhoc_namespaces[namespace] = 'x' + (@adhoc_namespaces.size + 1).to_s end result = start_element_ns(@adhoc_namespaces[namespace], local_name, namespace) end else result = @writer.start_element(name) end unless @namespaces_written @namespace_map.each do |ns, prefix| write_attribute((prefix.present? ? 'xmlns:' + prefix : 'xmlns'), ns) end @namespaces_written = true end result end |
#write(value) ⇒ void
This method returns an undefined value.
Writes a value to the output stream.
The following values are supported:
1. Scalar values will be written as-is, as text.
2. Null values will be skipped (resulting in a short xml tag).
3. If a value is an instance of an Element class, writing will be
delegated to the object.
4. If a value is an array, two formats are supported.
Array format 1:
[
"{namespace}name1" => "..",
"{namespace}name2" => "..",
]
One element will be created for each key in this array. The values of
this array support any format this method supports (this method is
called recursively).
Array format 2:
[
[
"name" => "{namespace}name1"
"value" => "..",
"attributes" => [
"attr" => "attribute value",
]
],
[
"name" => "{namespace}name1"
"value" => "..",
"attributes" => [
"attr" => "attribute value",
]
]
]
65 66 67 |
# File 'lib/tilia/xml/writer.rb', line 65 def write(value) Serializer.standard_serializer(self, value) end |
#write_attribute(name, value) ⇒ Boolean
Writes a new attribute.
The name may be specified in clark-notation.
Returns true when successful.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/tilia/xml/writer.rb', line 158 def write_attribute(name, value) if name[0] == '{' (namespace, local_name) = Service.parse_clark_notation(name) if @namespace_map.key?(namespace) # It's an attribute with a namespace we know write_attribute( @namespace_map[namespace] + ':' + local_name, value ) else # We don't know the namespace, we must add it in-line @adhoc_namespaces[namespace] = 'x' + (@adhoc_namespaces.size + 1).to_s unless @adhoc_namespaces.key?(namespace) write_attribute_ns( @adhoc_namespaces[namespace], local_name, namespace, value ) end else @writer.write_attribute(name, value) end end |
#write_attributes(attributes) ⇒ void
This method returns an undefined value.
Writes a list of attributes.
Attributes are specified as a key->value array.
The key is an attribute name. If the key is a ‘localName’, the current xml namespace is assumed. If it’s a ‘clark notation key’, this namespace will be used instead.
143 144 145 146 147 |
# File 'lib/tilia/xml/writer.rb', line 143 def write_attributes(attributes) attributes.each do |name, value| write_attribute(name, value) end end |
#write_element(name, content = nil) ⇒ Boolean
Write a full element tag and it’s contents.
This method automatically closes the element as well.
The element name may be specified in clark-notation.
Examples:
writer.write_element('{http://www.w3.org/2005/Atom}author',null)
becomes:
<author xmlns="http://www.w3.org/2005" />
writer.write_element('{http://www.w3.org/2005/Atom}author', [
'{http://www.w3.org/2005/Atom}name' => 'Evert Pot',
])
becomes:
<author xmlns="http://www.w3.org/2005" /><name>Evert Pot</name></author>
127 128 129 130 131 |
# File 'lib/tilia/xml/writer.rb', line 127 def write_element(name, content = nil) start_element(name) write(content) unless content.nil? end_element end |