HRESULT node_remove_child(xmlnode *This, IXMLDOMNode* child, IXMLDOMNode** oldChild) { xmlnode *child_node; if(!child) return E_INVALIDARG; if(oldChild) *oldChild = NULL; child_node = get_node_obj(child); if(!child_node) return E_FAIL; if(child_node->node->parent != This->node) { WARN("childNode %p is not a child of %p\n", child, This); return E_INVALIDARG; } xmlUnlinkNode(child_node->node); child_node->parent = NULL; xmldoc_add_orphan(child_node->node->doc, child_node->node); if(oldChild) { IXMLDOMNode_AddRef(child); *oldChild = child; } return S_OK; }
HRESULT node_clone(xmlnode *This, VARIANT_BOOL deep, IXMLDOMNode **cloneNode) { IXMLDOMNode *node; xmlNodePtr clone; if(!cloneNode) return E_INVALIDARG; clone = xmlCopyNode(This->node, deep ? 1 : 2); if (clone) { xmlSetTreeDoc(clone, This->node->doc); xmldoc_add_orphan(clone->doc, clone); node = create_node(clone); if (!node) { ERR("Copy failed\n"); xmldoc_remove_orphan(clone->doc, clone); xmlFreeNode(clone); return E_FAIL; } *cloneNode = node; } else { ERR("Copy failed\n"); return E_FAIL; } return S_OK; }
static HRESULT WINAPI xmlnodemap_removeQualifiedItem( IXMLDOMNamedNodeMap *iface, BSTR baseName, BSTR namespaceURI, IXMLDOMNode** qualifiedItem) { xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); xmlAttrPtr attr; xmlChar *name; xmlChar *href; TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), qualifiedItem); if (!baseName) return E_INVALIDARG; if (namespaceURI && *namespaceURI) { href = xmlchar_from_wchar(namespaceURI); if (!href) return E_OUTOFMEMORY; } else href = NULL; name = xmlchar_from_wchar(baseName); if (!name) { heap_free(href); return E_OUTOFMEMORY; } attr = xmlHasNsProp( This->node, name, href ); heap_free(name); heap_free(href); if ( !attr ) { if (qualifiedItem) *qualifiedItem = NULL; return S_FALSE; } if ( qualifiedItem ) { xmlUnlinkNode( (xmlNodePtr) attr ); xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr ); *qualifiedItem = create_node( (xmlNodePtr) attr ); } else { if (xmlRemoveProp(attr) == -1) ERR("xmlRemoveProp failed\n"); } return S_OK; }
HRESULT node_replace_child(xmlnode *This, IXMLDOMNode *newChild, IXMLDOMNode *oldChild, IXMLDOMNode **ret) { xmlnode *old_child, *new_child; xmlDocPtr leaving_doc; xmlNode *my_ancestor; int refcount = 0; /* Do not believe any documentation telling that newChild == NULL means removal. It does certainly *not* apply to msxml3! */ if(!newChild || !oldChild) return E_INVALIDARG; if(ret) *ret = NULL; old_child = get_node_obj(oldChild); if(!old_child) return E_FAIL; if(old_child->node->parent != This->node) { WARN("childNode %p is not a child of %p\n", oldChild, This); return E_INVALIDARG; } new_child = get_node_obj(newChild); if(!new_child) return E_FAIL; my_ancestor = This->node; while(my_ancestor) { if(my_ancestor == new_child->node) { WARN("tried to create loop\n"); return E_FAIL; } my_ancestor = my_ancestor->parent; } if(!new_child->node->parent) if(xmldoc_remove_orphan(new_child->node->doc, new_child->node) != S_OK) WARN("%p is not an orphan of %p\n", new_child->node, new_child->node->doc); leaving_doc = new_child->node->doc; if (leaving_doc != old_child->node->doc) refcount = xmlnode_get_inst_cnt(new_child); if (refcount) xmldoc_add_refs(old_child->node->doc, refcount); xmlReplaceNode(old_child->node, new_child->node); if (refcount) xmldoc_release_refs(leaving_doc, refcount); new_child->parent = old_child->parent; old_child->parent = NULL; xmldoc_add_orphan(old_child->node->doc, old_child->node); if(ret) { IXMLDOMNode_AddRef(oldChild); *ret = oldChild; } return S_OK; }