tilia-xml 1.2.0.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.simplecov +1 -2
- data/CHANGELOG.sabre.md +21 -0
- data/Gemfile +2 -7
- data/Gemfile.lock +22 -17
- data/LICENSE +1 -1
- data/LICENSE.sabre +1 -1
- data/lib/tilia/xml.rb +3 -0
- data/lib/tilia/xml/context_stack_trait.rb +27 -23
- data/lib/tilia/xml/deserializer.rb +241 -0
- data/lib/tilia/xml/element/base.rb +2 -43
- data/lib/tilia/xml/element/cdata.rb +1 -26
- data/lib/tilia/xml/element/elements.rb +4 -66
- data/lib/tilia/xml/element/key_value.rb +3 -65
- data/lib/tilia/xml/element/uri.rb +2 -45
- data/lib/tilia/xml/element/xml_fragment.rb +2 -42
- data/lib/tilia/xml/reader.rb +33 -28
- data/lib/tilia/xml/serializer.rb +194 -0
- data/lib/tilia/xml/service.rb +98 -14
- data/lib/tilia/xml/version.rb +1 -1
- data/lib/tilia/xml/writer.rb +42 -88
- data/lib/tilia/xml/xml_deserializable.rb +4 -4
- data/lib/tilia/xml/xml_serializable.rb +3 -3
- data/test/test_helper.rb +77 -0
- data/test/xml/context_stack_test.rb +0 -3
- data/test/xml/deserializer/enum_test.rb +55 -0
- data/test/xml/deserializer/key_value_test.rb +64 -0
- data/test/xml/deserializer/repeating_elements_test.rb +33 -0
- data/test/xml/deserializer/value_object_test.rb +163 -0
- data/test/xml/reader_test.rb +35 -16
- data/test/xml/serializer/enum_test.rb +36 -0
- data/test/xml/serializer/repeating_elements_test.rb +37 -0
- data/test/xml/service_test.rb +68 -0
- data/test/xml/writer_test.rb +120 -17
- data/tilia-xml.gemspec +4 -4
- metadata +23 -9
@@ -0,0 +1,194 @@
|
|
1
|
+
module Tilia
|
2
|
+
module Xml
|
3
|
+
# This file provides a number of 'serializer' helper functions.
|
4
|
+
#
|
5
|
+
# These helper functions can be used to easily xml-encode common PHP
|
6
|
+
# data structures, or can be placed in the class_map.
|
7
|
+
module Serializer
|
8
|
+
# The 'enum' serializer writes simple list of elements.
|
9
|
+
#
|
10
|
+
# For example, calling:
|
11
|
+
#
|
12
|
+
# enum(writer, [
|
13
|
+
# "{http://sabredav.org/ns}elem1",
|
14
|
+
# "{http://sabredav.org/ns}elem2",
|
15
|
+
# "{http://sabredav.org/ns}elem3",
|
16
|
+
# "{http://sabredav.org/ns}elem4",
|
17
|
+
# "{http://sabredav.org/ns}elem5",
|
18
|
+
# ])
|
19
|
+
#
|
20
|
+
# Will generate something like this (if the correct namespace is declared):
|
21
|
+
#
|
22
|
+
# <s:elem1 />
|
23
|
+
# <s:elem2 />
|
24
|
+
# <s:elem3 />
|
25
|
+
# <s:elem4>content</s:elem4>
|
26
|
+
# <s:elem5 attr="val" />
|
27
|
+
#
|
28
|
+
# @param [Writer] writer
|
29
|
+
# @param [Array<String>] values
|
30
|
+
# @return [void]
|
31
|
+
def self.enum(writer, values)
|
32
|
+
values.each do |value|
|
33
|
+
writer.write_element(value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# The valueObject serializer turns a simple PHP object into a classname.
|
38
|
+
#
|
39
|
+
# Every public property will be encoded as an xml element with the same
|
40
|
+
# name, in the XML namespace as specified.
|
41
|
+
#
|
42
|
+
# @param [Writer] writer
|
43
|
+
# @param [Object] value_object
|
44
|
+
# @param [String] namespace
|
45
|
+
def self.value_object(writer, value_object, namespace)
|
46
|
+
value_object.instance_variables.each do |key|
|
47
|
+
value = value_object.instance_variable_get(key)
|
48
|
+
|
49
|
+
# key is a symbol and starts with @
|
50
|
+
key = key.to_s[1..-1]
|
51
|
+
|
52
|
+
writer.write_element("{#{namespace}}#{key}", value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# This serializer helps you serialize xml structures that look like
|
57
|
+
# this:
|
58
|
+
#
|
59
|
+
# <collection>
|
60
|
+
# <item>...</item>
|
61
|
+
# <item>...</item>
|
62
|
+
# <item>...</item>
|
63
|
+
# </collection>
|
64
|
+
#
|
65
|
+
# In that previous example, this serializer just serializes the item element,
|
66
|
+
# and this could be called like this:
|
67
|
+
#
|
68
|
+
# repeating_elements(writer, items, '{}item')
|
69
|
+
#
|
70
|
+
# @param [Writer] writer
|
71
|
+
# @param [Array] items A list of items sabre/xml can serialize.
|
72
|
+
# @param [String] child_element_name Element name in clark-notation
|
73
|
+
# @return [void]
|
74
|
+
def self.repeating_elements(writer, items, child_element_name)
|
75
|
+
items.each do |item|
|
76
|
+
writer.write_element(child_element_name, item)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# This function is the 'default' serializer that is able to serialize most
|
81
|
+
# things, and delegates to other serializers if needed.
|
82
|
+
#
|
83
|
+
# The standardSerializer supports a wide-array of values.
|
84
|
+
#
|
85
|
+
# value may be a string or integer, it will just write out the string as text.
|
86
|
+
# value may be an instance of XmlSerializable or Element, in which case it
|
87
|
+
# calls it's xml_serialize method.
|
88
|
+
# value may be a PHP callback/function/closure, in case we call the callback
|
89
|
+
# and give it the Writer as an argument.
|
90
|
+
# value may be a an object, and if it's in the classMap we automatically call
|
91
|
+
# the correct serializer for it.
|
92
|
+
# value may be null, in which case we do nothing.
|
93
|
+
#
|
94
|
+
# If value is an array, the array must look like this:
|
95
|
+
#
|
96
|
+
# [
|
97
|
+
# [
|
98
|
+
# 'name' => '{namespaceUri}element-name',
|
99
|
+
# 'value' => '...',
|
100
|
+
# 'attributes' => [ 'attName' => 'attValue' ]
|
101
|
+
# ]
|
102
|
+
# [,
|
103
|
+
# 'name' => '{namespaceUri}element-name2',
|
104
|
+
# 'value' => '...',
|
105
|
+
# ]
|
106
|
+
# ]
|
107
|
+
#
|
108
|
+
# This would result in xml like:
|
109
|
+
#
|
110
|
+
# <element-name xmlns="namespaceUri" attName="attValue">
|
111
|
+
# ...
|
112
|
+
# </element-name>
|
113
|
+
# <element-name2>
|
114
|
+
# ...
|
115
|
+
# </element-name2>
|
116
|
+
#
|
117
|
+
# The value property may be any value standardSerializer supports, so you can
|
118
|
+
# nest data-structures this way. Both value and attributes are optional.
|
119
|
+
#
|
120
|
+
# Alternatively, you can also specify the array using this syntax:
|
121
|
+
#
|
122
|
+
# [
|
123
|
+
# [
|
124
|
+
# '{namespaceUri}element-name' => '...',
|
125
|
+
# '{namespaceUri}element-name2' => '...',
|
126
|
+
# ]
|
127
|
+
# ]
|
128
|
+
#
|
129
|
+
# This is excellent for simple key.value structures, and here you can also
|
130
|
+
# specify anything for the value.
|
131
|
+
#
|
132
|
+
# You can even mix the two array syntaxes.
|
133
|
+
#
|
134
|
+
# @param [Writer] writer
|
135
|
+
# @param value
|
136
|
+
# @return [void]
|
137
|
+
def self.standard_serializer(writer, value)
|
138
|
+
if value.is_a?(Numeric) || value.is_a?(String)
|
139
|
+
writer.write_string(value.to_s)
|
140
|
+
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
141
|
+
writer.write_string(value.to_s)
|
142
|
+
elsif value.is_a?(XmlSerializable)
|
143
|
+
value.xml_serialize(writer)
|
144
|
+
elsif writer.class_map.key?(value.class)
|
145
|
+
# It's an object which class appears in the classmap.
|
146
|
+
writer.class_map[value.class].call(writer, value)
|
147
|
+
elsif value.respond_to?(:call)
|
148
|
+
# A callback
|
149
|
+
value.call(writer)
|
150
|
+
elsif value.nil?
|
151
|
+
# noop
|
152
|
+
elsif value.is_a?(Hash) || value.is_a?(Array)
|
153
|
+
# Code for ruby implementation
|
154
|
+
if value.is_a?(Array)
|
155
|
+
hash = {}
|
156
|
+
value.each_with_index do |v, i|
|
157
|
+
hash[i] = v
|
158
|
+
end
|
159
|
+
value = hash
|
160
|
+
end
|
161
|
+
|
162
|
+
value.each do |name, item|
|
163
|
+
if name.is_a? Fixnum
|
164
|
+
# This item has a numeric index. We expect to be an array with a name and a value.
|
165
|
+
unless item.is_a?(Hash) && item.key?('name')
|
166
|
+
raise ArgumentError, 'When passing an array to ->write with numeric indices, every item must be an array containing at least the "name" key'
|
167
|
+
end
|
168
|
+
|
169
|
+
attributes = item.key?('attributes') ? item['attributes'] : []
|
170
|
+
name = item['name']
|
171
|
+
item = item['value'] || []
|
172
|
+
elsif item.is_a?(Hash) && item.key?('value')
|
173
|
+
# This item has a text index. We expect to be an array with a value and optional attributes.
|
174
|
+
attributes = item.key?('attributes') ? item['attributes'] : []
|
175
|
+
item = item['value']
|
176
|
+
else
|
177
|
+
# If it's an array with text-indices, we expect every item's
|
178
|
+
# key to be an xml element name in clark notation.
|
179
|
+
# No attributes can be passed.
|
180
|
+
attributes = []
|
181
|
+
end
|
182
|
+
|
183
|
+
writer.start_element(name)
|
184
|
+
writer.write_attributes(attributes)
|
185
|
+
writer.write(item)
|
186
|
+
writer.end_element
|
187
|
+
end
|
188
|
+
else
|
189
|
+
raise ArgumentError, "The writer cannot serialize objects of type: #{value.class}"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
data/lib/tilia/xml/service.rb
CHANGED
@@ -25,6 +25,32 @@ module Tilia
|
|
25
25
|
# @return [Hash]
|
26
26
|
attr_accessor :namespace_map
|
27
27
|
|
28
|
+
# This is a list of custom serializers for specific classes.
|
29
|
+
#
|
30
|
+
# The writer may use this if you attempt to serialize an object with a
|
31
|
+
# class that does not implement XmlSerializable.
|
32
|
+
#
|
33
|
+
# Instead it will look at this classmap to see if there is a custom
|
34
|
+
# serializer here. This is useful if you don't want your value objects
|
35
|
+
# to be responsible for serializing themselves.
|
36
|
+
#
|
37
|
+
# The keys in this classmap need to be fully qualified PHP class names,
|
38
|
+
# the values must be callbacks. The callbacks take two arguments. The
|
39
|
+
# writer class, and the value that must be written.
|
40
|
+
#
|
41
|
+
# function (Writer writer, object value)
|
42
|
+
#
|
43
|
+
# @return [Hash]
|
44
|
+
attr_accessor :class_map
|
45
|
+
|
46
|
+
# Initializes the xml service
|
47
|
+
def initialize
|
48
|
+
@element_map = {}
|
49
|
+
@namespace_map = {}
|
50
|
+
@class_map = {}
|
51
|
+
@value_object_map = {}
|
52
|
+
end
|
53
|
+
|
28
54
|
# Returns a fresh XML Reader
|
29
55
|
#
|
30
56
|
# @return [Reader]
|
@@ -40,6 +66,7 @@ module Tilia
|
|
40
66
|
def writer
|
41
67
|
writer = Writer.new
|
42
68
|
writer.namespace_map = @namespace_map
|
69
|
+
writer.class_map = @class_map
|
43
70
|
writer
|
44
71
|
end
|
45
72
|
|
@@ -57,7 +84,7 @@ module Tilia
|
|
57
84
|
#
|
58
85
|
# @param [String, File, StringIO] input
|
59
86
|
# @param [String, nil] context_uri
|
60
|
-
# @param [
|
87
|
+
# @param [Tilia::Box, nil] root_element_name
|
61
88
|
# @raise [ParseException]
|
62
89
|
# @return [Array, Object, String]
|
63
90
|
def parse(input, context_uri = nil, root_element_name = Box.new)
|
@@ -81,19 +108,20 @@ module Tilia
|
|
81
108
|
# This is useful in cases where you expected a specific document to be
|
82
109
|
# passed, and reduces the amount of if statements.
|
83
110
|
#
|
84
|
-
# @param [String] root_element_name
|
111
|
+
# @param [String, Array<String>] root_element_name
|
85
112
|
# @param [String, File, StringIO] input
|
86
113
|
# @param [String, nil] context_uri
|
87
114
|
# @return [void]
|
88
115
|
def expect(root_element_name, input, context_uri = nil)
|
89
|
-
|
116
|
+
root_element_name = [root_element_name] unless root_element_name.is_a?(Array)
|
117
|
+
|
90
118
|
reader = self.reader
|
91
119
|
reader.context_uri = context_uri
|
92
120
|
reader.xml(input)
|
93
121
|
|
94
122
|
result = reader.parse
|
95
|
-
|
96
|
-
|
123
|
+
unless root_element_name.include?(result['name'])
|
124
|
+
raise Tilia::Xml::ParseException, "Expected #{root_element_name.join(' or ')} but received #{result['name']} as the root element"
|
97
125
|
end
|
98
126
|
result['value']
|
99
127
|
end
|
@@ -125,6 +153,68 @@ module Tilia
|
|
125
153
|
writer.output_memory
|
126
154
|
end
|
127
155
|
|
156
|
+
# Map an xml element to a PHP class.
|
157
|
+
#
|
158
|
+
# Calling this function will automatically setup the Reader and Writer
|
159
|
+
# classes to turn a specific XML element to a PHP class.
|
160
|
+
#
|
161
|
+
# For example, given a class such as :
|
162
|
+
#
|
163
|
+
# class Author {
|
164
|
+
# public first_name
|
165
|
+
# public last_name
|
166
|
+
# }
|
167
|
+
#
|
168
|
+
# and an XML element such as:
|
169
|
+
#
|
170
|
+
# <author xmlns="http://example.org/ns">
|
171
|
+
# <firstName>...</firstName>
|
172
|
+
# <lastName>...</lastName>
|
173
|
+
# </author>
|
174
|
+
#
|
175
|
+
# These can easily be mapped by calling:
|
176
|
+
#
|
177
|
+
# service.map_value_object('{http://example.org}author', 'Author')
|
178
|
+
#
|
179
|
+
# @param [String] element_name
|
180
|
+
# @param [Class] klass
|
181
|
+
# @return [void]
|
182
|
+
def map_value_object(element_name, klass)
|
183
|
+
namespace = Service.parse_clark_notation(element_name).first
|
184
|
+
|
185
|
+
@element_map[element_name] = lambda do |reader|
|
186
|
+
return Deserializer.value_object(reader, klass, namespace)
|
187
|
+
end
|
188
|
+
@class_map[klass] = lambda do |writer, value_object|
|
189
|
+
return Serializer.value_object(writer, value_object, namespace)
|
190
|
+
end
|
191
|
+
@value_object_map[klass] = element_name
|
192
|
+
end
|
193
|
+
|
194
|
+
# Writes a value object.
|
195
|
+
#
|
196
|
+
# This function largely behaves similar to write, except that it's
|
197
|
+
# intended specifically to serialize a Value Object into an XML document.
|
198
|
+
#
|
199
|
+
# The ValueObject must have been previously registered using
|
200
|
+
# map_value_object.
|
201
|
+
#
|
202
|
+
# @param object
|
203
|
+
# @param [String] context_uri
|
204
|
+
# @return [void]
|
205
|
+
def write_value_object(object, context_uri = nil)
|
206
|
+
unless @value_object_map.key?(object.class)
|
207
|
+
raise ArgumentError,
|
208
|
+
"'#{object.class}' is not a registered value object class. Register your class with mapValueObject"
|
209
|
+
end
|
210
|
+
|
211
|
+
write(
|
212
|
+
@value_object_map[object.class],
|
213
|
+
object,
|
214
|
+
context_uri
|
215
|
+
)
|
216
|
+
end
|
217
|
+
|
128
218
|
# Parses a clark-notation string, and returns the namespace and element
|
129
219
|
# name components.
|
130
220
|
#
|
@@ -132,20 +222,14 @@ module Tilia
|
|
132
222
|
#
|
133
223
|
# @param [String] str
|
134
224
|
# @raise [InvalidArgumentException]
|
135
|
-
# @return [Array]
|
225
|
+
# @return [Array(String, String)]
|
136
226
|
def self.parse_clark_notation(str)
|
137
227
|
if str =~ /^{([^}]*)}(.*)/
|
138
|
-
[Regexp.last_match[1], Regexp.last_match[2]]
|
228
|
+
[Regexp.last_match[1] || '', Regexp.last_match[2]]
|
139
229
|
else
|
140
|
-
|
230
|
+
raise ArgumentError, "'#{str}' is not a valid clark-notation formatted string"
|
141
231
|
end
|
142
232
|
end
|
143
|
-
|
144
|
-
# TODO: document
|
145
|
-
def initialize
|
146
|
-
@element_map = {}
|
147
|
-
@namespace_map = {}
|
148
|
-
end
|
149
233
|
end
|
150
234
|
end
|
151
235
|
end
|
data/lib/tilia/xml/version.rb
CHANGED
data/lib/tilia/xml/writer.rb
CHANGED
@@ -22,27 +22,6 @@ module Tilia
|
|
22
22
|
class Writer
|
23
23
|
include ContextStackTrait
|
24
24
|
|
25
|
-
protected
|
26
|
-
|
27
|
-
# Any namespace that the writer is asked to write, will be added here.
|
28
|
-
#
|
29
|
-
# Any of these elements will get a new namespace definition *every single
|
30
|
-
# time* they are used, but this array allows the writer to make sure that
|
31
|
-
# the prefixes are consistent anyway.
|
32
|
-
#
|
33
|
-
# @return [Hash]
|
34
|
-
attr_accessor :adhoc_namespaces
|
35
|
-
|
36
|
-
# When the first element is written, this flag is set to true.
|
37
|
-
#
|
38
|
-
# This ensures that the namespaces in the namespaces map are only written
|
39
|
-
# once.
|
40
|
-
#
|
41
|
-
# @return [Boolean]
|
42
|
-
attr_accessor :namespaces_written
|
43
|
-
|
44
|
-
public
|
45
|
-
|
46
25
|
# Writes a value to the output stream.
|
47
26
|
#
|
48
27
|
# The following values are supported:
|
@@ -84,53 +63,7 @@ module Tilia
|
|
84
63
|
# @param value
|
85
64
|
# @return [void]
|
86
65
|
def write(value)
|
87
|
-
|
88
|
-
write_string(value.to_s)
|
89
|
-
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
90
|
-
write_string(value.to_s)
|
91
|
-
elsif value.is_a? XmlSerializable
|
92
|
-
value.xml_serialize(self)
|
93
|
-
elsif value.nil?
|
94
|
-
# noop
|
95
|
-
elsif value.is_a?(Hash) || value.is_a?(Array)
|
96
|
-
# Code for ruby implementation
|
97
|
-
if value.is_a?(Array)
|
98
|
-
hash = {}
|
99
|
-
value.each_with_index do |v, i|
|
100
|
-
hash[i] = v
|
101
|
-
end
|
102
|
-
value = hash
|
103
|
-
end
|
104
|
-
|
105
|
-
value.each do |name, item|
|
106
|
-
if name.is_a? Fixnum
|
107
|
-
# This item has a numeric index. We expect to be an array with a name and a value.
|
108
|
-
unless item.is_a?(Hash) && item.key?('name') && item.key?('value')
|
109
|
-
fail ArgumentError, 'When passing an array to ->write with numeric indices, every item must be an array containing the "name" and "value" key'
|
110
|
-
end
|
111
|
-
|
112
|
-
attributes = item.key?('attributes') ? item['attributes'] : []
|
113
|
-
name = item['name']
|
114
|
-
item = item['value']
|
115
|
-
elsif item.is_a?(Hash) && item.key?('value')
|
116
|
-
# This item has a text index. We expect to be an array with a value and optional attributes.
|
117
|
-
attributes = item.key?('attributes') ? item['attributes'] : []
|
118
|
-
item = item['value']
|
119
|
-
else
|
120
|
-
# If it's an array with text-indices, we expect every item's
|
121
|
-
# key to be an xml element name in clark notation.
|
122
|
-
# No attributes can be passed.
|
123
|
-
attributes = []
|
124
|
-
end
|
125
|
-
|
126
|
-
start_element(name)
|
127
|
-
write_attributes(attributes)
|
128
|
-
write(item)
|
129
|
-
end_element
|
130
|
-
end
|
131
|
-
else
|
132
|
-
fail ArgumentError, "The writer cannot serialize objects of type: #{value.class}"
|
133
|
-
end
|
66
|
+
Serializer.standard_serializer(self, value)
|
134
67
|
end
|
135
68
|
|
136
69
|
# Starts an element.
|
@@ -141,20 +74,20 @@ module Tilia
|
|
141
74
|
if name[0] == '{'
|
142
75
|
(namespace, local_name) = Service.parse_clark_notation(name)
|
143
76
|
|
144
|
-
if @namespace_map.key?
|
145
|
-
|
146
|
-
|
77
|
+
if @namespace_map.key?(namespace)
|
78
|
+
tmp_ns = @namespace_map[namespace]
|
79
|
+
tmp_ns = nil if tmp_ns.blank?
|
80
|
+
result = start_element_ns(tmp_ns, local_name, nil)
|
81
|
+
elsif namespace.blank?
|
147
82
|
# An empty namespace means it's the global namespace. This is
|
148
83
|
# allowed, but it mustn't get a prefix.
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
@adhoc_namespaces[namespace] = 'x' + (@adhoc_namespaces.size + 1).to_s
|
155
|
-
end
|
156
|
-
result = start_element_ns(@adhoc_namespaces[namespace], local_name, namespace)
|
84
|
+
result = start_element(local_name)
|
85
|
+
write_attribute('xmlns', '')
|
86
|
+
else
|
87
|
+
unless @adhoc_namespaces.key?(namespace)
|
88
|
+
@adhoc_namespaces[namespace] = 'x' + (@adhoc_namespaces.size + 1).to_s
|
157
89
|
end
|
90
|
+
result = start_element_ns(@adhoc_namespaces[namespace], local_name, namespace)
|
158
91
|
end
|
159
92
|
else
|
160
93
|
result = @writer.start_element(name)
|
@@ -162,7 +95,7 @@ module Tilia
|
|
162
95
|
|
163
96
|
unless @namespaces_written
|
164
97
|
@namespace_map.each do |ns, prefix|
|
165
|
-
write_attribute((prefix ? 'xmlns:' + prefix : 'xmlns'), ns)
|
98
|
+
write_attribute((prefix.present? ? 'xmlns:' + prefix : 'xmlns'), ns)
|
166
99
|
end
|
167
100
|
@namespaces_written = true
|
168
101
|
end
|
@@ -170,10 +103,24 @@ module Tilia
|
|
170
103
|
result
|
171
104
|
end
|
172
105
|
|
173
|
-
# Write a full element tag.
|
106
|
+
# Write a full element tag and it's contents.
|
174
107
|
#
|
175
108
|
# This method automatically closes the element as well.
|
176
109
|
#
|
110
|
+
# The element name may be specified in clark-notation.
|
111
|
+
#
|
112
|
+
# Examples:
|
113
|
+
#
|
114
|
+
# writer.write_element('{http://www.w3.org/2005/Atom}author',null)
|
115
|
+
# becomes:
|
116
|
+
# <author xmlns="http://www.w3.org/2005" />
|
117
|
+
#
|
118
|
+
# writer.write_element('{http://www.w3.org/2005/Atom}author', [
|
119
|
+
# '{http://www.w3.org/2005/Atom}name' => 'Evert Pot',
|
120
|
+
# ])
|
121
|
+
# becomes:
|
122
|
+
# <author xmlns="http://www.w3.org/2005" /><name>Evert Pot</name></author>
|
123
|
+
#
|
177
124
|
# @param [String] name
|
178
125
|
# @param [String] content
|
179
126
|
# @return [Boolean]
|
@@ -211,7 +158,7 @@ module Tilia
|
|
211
158
|
def write_attribute(name, value)
|
212
159
|
if name[0] == '{'
|
213
160
|
(namespace, local_name) = Service.parse_clark_notation(name)
|
214
|
-
if @namespace_map.key?
|
161
|
+
if @namespace_map.key?(namespace)
|
215
162
|
# It's an attribute with a namespace we know
|
216
163
|
write_attribute(
|
217
164
|
@namespace_map[namespace] + ':' + local_name,
|
@@ -233,26 +180,33 @@ module Tilia
|
|
233
180
|
end
|
234
181
|
end
|
235
182
|
|
236
|
-
#
|
183
|
+
# Initializes the instance variables
|
237
184
|
def initialize
|
238
185
|
@adhoc_namespaces = {}
|
239
186
|
@namespaces_written = false
|
240
|
-
|
187
|
+
|
188
|
+
super
|
241
189
|
end
|
242
190
|
|
243
|
-
#
|
191
|
+
# Fakes the php function open_memory
|
192
|
+
#
|
193
|
+
# Initilizes the LibXML Writer
|
194
|
+
#
|
195
|
+
# @return [void]
|
244
196
|
def open_memory
|
245
|
-
|
197
|
+
raise 'XML document already created' if @writer
|
246
198
|
|
247
199
|
@writer = ::LibXML::XML::Writer.string
|
248
200
|
end
|
249
201
|
|
250
|
-
#
|
202
|
+
# Fakes the php function output_memory
|
203
|
+
#
|
204
|
+
# @return [String]
|
251
205
|
def output_memory
|
252
206
|
@writer.result
|
253
207
|
end
|
254
208
|
|
255
|
-
#
|
209
|
+
# Delegates missing methods to XML::Writer instance
|
256
210
|
def method_missing(name, *args)
|
257
211
|
@writer.send(name, *args)
|
258
212
|
end
|