@@ -88,7 +88,7 @@ local function remove_namespace(node, prefix)
88
88
end
89
89
end
90
90
91
- namespace = node .nsDef
91
+ local namespace = node .nsDef
92
92
local namespace_previous = nil
93
93
while namespace ~= ffi .NULL do
94
94
if is_target_namespace (namespace ) then
@@ -127,65 +127,67 @@ local function set_attributes(element, attributes)
127
127
end
128
128
end
129
129
130
- local function create_sub_element (document , node , name , attributes )
130
+ local function create_sub_element (document , parent , name , attributes )
131
131
local namespace_prefix , local_name = parse_name (name )
132
- local raw_element = libxml2 .xmlNewNode (nil , local_name )
133
- local element = Element .new (document , raw_element )
132
+ local node = libxml2 .xmlNewNode (nil , local_name )
133
+ local element = Element .new (document , node )
134
134
set_attributes (element , attributes )
135
- local namespace = libxml2 .xmlSearchNs (document , raw_element , namespace_prefix )
136
- if not namespace and node then
137
- namespace = libxml2 .xmlSearchNs (document , node , namespace_prefix )
135
+ local namespace = libxml2 .xmlSearchNs (document . raw_document , node , namespace_prefix )
136
+ if not namespace and parent then
137
+ namespace = libxml2 .xmlSearchNs (document . raw_document , parent , namespace_prefix )
138
138
end
139
139
if namespace then
140
- libxml2 .xmlSetNs (raw_element , namespace )
140
+ libxml2 .xmlSetNs (node , namespace )
141
141
elseif namespace_prefix then
142
142
element :unlink ()
143
- raw_element = libxml2 .xmlNewNode (nil , name )
144
- element = Element .new (document , raw_element )
143
+ node = libxml2 .xmlNewNode (nil , name )
144
+ element = Element .new (document , node )
145
145
set_attributes (element , attributes )
146
146
end
147
147
return element
148
148
end
149
149
150
- function methods :add_child (node )
151
- if node .node .parent ~= ffi .NULL then
152
- node :unlink ()
153
- end
154
- local raw_added_node =
155
- libxml2 .xmlAddChild (self .node , node .node )
156
- if raw_added_node ~= ffi .NULL then
157
- ffi .gc (node .node , nil )
150
+ function methods :add_child (element )
151
+ local node
152
+ if self .document == element .document then
153
+ if element .node .parent ~= ffi .NULL then
154
+ element :unlink ()
155
+ end
156
+ node = element .node
157
+ else
158
+ node = libxml2 .xmlCopyNode (element .node , self .document .raw_document )
158
159
end
160
+ libxml2 .xmlAddChild (self .node , node )
159
161
end
160
162
161
- function methods :add_previous_sibling (node )
162
- if not self .node and not node .node then
163
+ function methods :add_previous_sibling (element )
164
+ if not self .node and not element .node then
163
165
error (" Already freed receiver node and added node" )
164
166
elseif not self .node then
165
167
error (" Already freed receiver node" )
166
- elseif not node .node then
168
+ elseif not element .node then
167
169
error (" Already freed added node" )
168
170
end
169
171
170
172
local raw_added_node , was_freed =
171
- libxml2 .xmlAddPrevSibling (self .node , node .node )
173
+ libxml2 .xmlAddPrevSibling (self .node , element .node )
172
174
if was_freed then
173
- node .node = nil
175
+ element .node = nil
174
176
end
175
177
end
176
178
177
- function methods :append_sibling (node )
178
- if not self .node and not node .node then
179
+ function methods :append_sibling (element )
180
+ if not self .node and not element .node then
179
181
error (" Already freed receiver node and appended node" )
180
182
elseif not self .node then
181
183
error (" Already freed receiver node" )
182
- elseif not node .node then
184
+ elseif not element .node then
183
185
error (" Already freed appended node" )
184
186
end
185
187
186
- local was_freed = libxml2 .xmlAddSibling (self .node , node .node )
188
+ local was_freed = libxml2 .xmlAddSibling (self .node , element .node )
187
189
if was_freed then
188
- node .node = nil
190
+ element .node = nil
189
191
end
190
192
end
191
193
@@ -256,28 +258,28 @@ function methods:insert_element(position, name, attributes)
256
258
end
257
259
258
260
function methods :unlink ()
259
- local unlinked_node = Node .unlink (self )
260
- return Element . new ( nil , unlinked_node )
261
+ Node .unlink (self )
262
+ return self
261
263
end
262
264
263
265
function methods :get_attribute (name )
264
266
local namespace_prefix , local_name = parse_name (name )
265
267
if namespace_prefix == " xmlns" then
266
- local namespace = libxml2 .xmlSearchNs (self .document , self .node , local_name )
268
+ local namespace = libxml2 .xmlSearchNs (self .document . raw_document , self .node , local_name )
267
269
if namespace then
268
270
return ffi .string (namespace .href )
269
271
else
270
272
return nil
271
273
end
272
274
elseif namespace_prefix == ffi .NULL and local_name == " xmlns" then
273
- local namespace = libxml2 .xmlSearchNs (self .document , self .node , nil )
275
+ local namespace = libxml2 .xmlSearchNs (self .document . raw_document , self .node , nil )
274
276
if namespace then
275
277
return ffi .string (namespace .href )
276
278
else
277
279
return nil
278
280
end
279
281
elseif namespace_prefix then
280
- local namespace = libxml2 .xmlSearchNs (self .document ,
282
+ local namespace = libxml2 .xmlSearchNs (self .document . raw_document ,
281
283
self .node ,
282
284
namespace_prefix )
283
285
if namespace then
@@ -298,7 +300,7 @@ function methods:set_attribute(name, value)
298
300
local namespace_prefix , local_name = parse_name (name )
299
301
local namespace
300
302
if namespace_prefix == " xmlns" then
301
- namespace = libxml2 .xmlSearchNs (self .document ,
303
+ namespace = libxml2 .xmlSearchNs (self .document . raw_document ,
302
304
self .node ,
303
305
local_name )
304
306
if namespace then
@@ -308,7 +310,7 @@ function methods:set_attribute(name, value)
308
310
libxml2 .xmlNewNs (self .node , value , local_name )
309
311
end
310
312
elseif namespace_prefix == nil and local_name == " xmlns" then
311
- namespace = libxml2 .xmlSearchNs (self .document , self .node , nil )
313
+ namespace = libxml2 .xmlSearchNs (self .document . raw_document , self .node , nil )
312
314
if namespace then
313
315
libxml2 .xmlFree (ffi .cast (" void *" , namespace .href ))
314
316
namespace .href = libxml2 .xmlStrdup (value )
@@ -317,7 +319,7 @@ function methods:set_attribute(name, value)
317
319
set_default_namespace (self .node , namespace )
318
320
end
319
321
elseif namespace_prefix then
320
- namespace = libxml2 .xmlSearchNs (self .document ,
322
+ namespace = libxml2 .xmlSearchNs (self .document . raw_document ,
321
323
self .node ,
322
324
namespace_prefix )
323
325
if namespace then
@@ -341,7 +343,7 @@ function methods:remove_attribute(name)
341
343
elseif namespace_prefix == nil and local_name == " xmlns" then
342
344
remove_namespace (self .node , nil )
343
345
elseif namespace_prefix then
344
- namespace = libxml2 .xmlSearchNs (self .document ,
346
+ namespace = libxml2 .xmlSearchNs (self .document . raw_document ,
345
347
self .node ,
346
348
namespace_prefix )
347
349
if namespace then
@@ -378,12 +380,12 @@ function methods:next()
378
380
end
379
381
380
382
function methods :root ()
381
- return Document . new ( self .document ) :root ()
383
+ return self .document :root ()
382
384
end
383
385
384
386
function methods :parent ()
385
387
if tonumber (self .node .parent .type ) == ffi .C .XML_DOCUMENT_NODE then
386
- return Document . new ( self .document )
388
+ return self .document
387
389
else
388
390
return Element .new (self .document , self .node .parent )
389
391
end
@@ -404,7 +406,7 @@ function methods:text()
404
406
end
405
407
406
408
function methods :namespaces ()
407
- local raw_namespaces = libxml2 .xmlGetNsList (self .document , self .node )
409
+ local raw_namespaces = libxml2 .xmlGetNsList (self .document . raw_document , self .node )
408
410
if not raw_namespaces then
409
411
return nil
410
412
end
@@ -427,23 +429,23 @@ function methods:find_namespace(prefix, href)
427
429
local raw_namespace
428
430
if not prefix and href then
429
431
raw_namespace =
430
- libxml2 .xmlSearchNsByHref (self .document , self .node , href )
432
+ libxml2 .xmlSearchNsByHref (self .document . raw_document , self .node , href )
431
433
else
432
434
raw_namespace =
433
- libxml2 .xmlSearchNs (self .document , self .node , prefix )
435
+ libxml2 .xmlSearchNs (self .document . raw_document , self .node , prefix )
434
436
end
435
437
return Namespace .new (self .document , raw_namespace )
436
438
end
437
439
438
440
-- For internal use
439
441
function Element .build (document , name , attributes )
440
- return create_sub_element (document . node , nil , name , attributes )
442
+ return create_sub_element (document , nil , name , attributes )
441
443
end
442
444
443
445
function Element .new (document , node )
444
446
local element = {
445
447
document = document ,
446
- node = node ,
448
+ node = node
447
449
}
448
450
setmetatable (element , metatable )
449
451
return element
0 commit comments