@@ -88,7 +88,7 @@ local function remove_namespace(node, prefix)
8888 end
8989 end
9090
91- namespace = node .nsDef
91+ local namespace = node .nsDef
9292 local namespace_previous = nil
9393 while namespace ~= ffi .NULL do
9494 if is_target_namespace (namespace ) then
@@ -127,65 +127,67 @@ local function set_attributes(element, attributes)
127127 end
128128end
129129
130- local function create_sub_element (document , node , name , attributes )
130+ local function create_sub_element (document , parent , name , attributes )
131131 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 )
134134 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 )
138138 end
139139 if namespace then
140- libxml2 .xmlSetNs (raw_element , namespace )
140+ libxml2 .xmlSetNs (node , namespace )
141141 elseif namespace_prefix then
142142 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 )
145145 set_attributes (element , attributes )
146146 end
147147 return element
148148end
149149
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 )
158159 end
160+ libxml2 .xmlAddChild (self .node , node )
159161end
160162
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
163165 error (" Already freed receiver node and added node" )
164166 elseif not self .node then
165167 error (" Already freed receiver node" )
166- elseif not node .node then
168+ elseif not element .node then
167169 error (" Already freed added node" )
168170 end
169171
170172 local raw_added_node , was_freed =
171- libxml2 .xmlAddPrevSibling (self .node , node .node )
173+ libxml2 .xmlAddPrevSibling (self .node , element .node )
172174 if was_freed then
173- node .node = nil
175+ element .node = nil
174176 end
175177end
176178
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
179181 error (" Already freed receiver node and appended node" )
180182 elseif not self .node then
181183 error (" Already freed receiver node" )
182- elseif not node .node then
184+ elseif not element .node then
183185 error (" Already freed appended node" )
184186 end
185187
186- local was_freed = libxml2 .xmlAddSibling (self .node , node .node )
188+ local was_freed = libxml2 .xmlAddSibling (self .node , element .node )
187189 if was_freed then
188- node .node = nil
190+ element .node = nil
189191 end
190192end
191193
@@ -256,28 +258,28 @@ function methods:insert_element(position, name, attributes)
256258end
257259
258260function methods :unlink ()
259- local unlinked_node = Node .unlink (self )
260- return Element . new ( nil , unlinked_node )
261+ Node .unlink (self )
262+ return self
261263end
262264
263265function methods :get_attribute (name )
264266 local namespace_prefix , local_name = parse_name (name )
265267 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 )
267269 if namespace then
268270 return ffi .string (namespace .href )
269271 else
270272 return nil
271273 end
272274 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 )
274276 if namespace then
275277 return ffi .string (namespace .href )
276278 else
277279 return nil
278280 end
279281 elseif namespace_prefix then
280- local namespace = libxml2 .xmlSearchNs (self .document ,
282+ local namespace = libxml2 .xmlSearchNs (self .document . raw_document ,
281283 self .node ,
282284 namespace_prefix )
283285 if namespace then
@@ -298,7 +300,7 @@ function methods:set_attribute(name, value)
298300 local namespace_prefix , local_name = parse_name (name )
299301 local namespace
300302 if namespace_prefix == " xmlns" then
301- namespace = libxml2 .xmlSearchNs (self .document ,
303+ namespace = libxml2 .xmlSearchNs (self .document . raw_document ,
302304 self .node ,
303305 local_name )
304306 if namespace then
@@ -308,7 +310,7 @@ function methods:set_attribute(name, value)
308310 libxml2 .xmlNewNs (self .node , value , local_name )
309311 end
310312 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 )
312314 if namespace then
313315 libxml2 .xmlFree (ffi .cast (" void *" , namespace .href ))
314316 namespace .href = libxml2 .xmlStrdup (value )
@@ -317,7 +319,7 @@ function methods:set_attribute(name, value)
317319 set_default_namespace (self .node , namespace )
318320 end
319321 elseif namespace_prefix then
320- namespace = libxml2 .xmlSearchNs (self .document ,
322+ namespace = libxml2 .xmlSearchNs (self .document . raw_document ,
321323 self .node ,
322324 namespace_prefix )
323325 if namespace then
@@ -341,7 +343,7 @@ function methods:remove_attribute(name)
341343 elseif namespace_prefix == nil and local_name == " xmlns" then
342344 remove_namespace (self .node , nil )
343345 elseif namespace_prefix then
344- namespace = libxml2 .xmlSearchNs (self .document ,
346+ namespace = libxml2 .xmlSearchNs (self .document . raw_document ,
345347 self .node ,
346348 namespace_prefix )
347349 if namespace then
@@ -378,12 +380,12 @@ function methods:next()
378380end
379381
380382function methods :root ()
381- return Document . new ( self .document ) :root ()
383+ return self .document :root ()
382384end
383385
384386function methods :parent ()
385387 if tonumber (self .node .parent .type ) == ffi .C .XML_DOCUMENT_NODE then
386- return Document . new ( self .document )
388+ return self .document
387389 else
388390 return Element .new (self .document , self .node .parent )
389391 end
@@ -404,7 +406,7 @@ function methods:text()
404406end
405407
406408function methods :namespaces ()
407- local raw_namespaces = libxml2 .xmlGetNsList (self .document , self .node )
409+ local raw_namespaces = libxml2 .xmlGetNsList (self .document . raw_document , self .node )
408410 if not raw_namespaces then
409411 return nil
410412 end
@@ -427,23 +429,23 @@ function methods:find_namespace(prefix, href)
427429 local raw_namespace
428430 if not prefix and href then
429431 raw_namespace =
430- libxml2 .xmlSearchNsByHref (self .document , self .node , href )
432+ libxml2 .xmlSearchNsByHref (self .document . raw_document , self .node , href )
431433 else
432434 raw_namespace =
433- libxml2 .xmlSearchNs (self .document , self .node , prefix )
435+ libxml2 .xmlSearchNs (self .document . raw_document , self .node , prefix )
434436 end
435437 return Namespace .new (self .document , raw_namespace )
436438end
437439
438440-- For internal use
439441function Element .build (document , name , attributes )
440- return create_sub_element (document . node , nil , name , attributes )
442+ return create_sub_element (document , nil , name , attributes )
441443end
442444
443445function Element .new (document , node )
444446 local element = {
445447 document = document ,
446- node = node ,
448+ node = node
447449 }
448450 setmetatable (element , metatable )
449451 return element
0 commit comments