From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/msxml3/attribute.c | 2 +- dlls/msxml3/element.c | 35 ++++++++++++++++++++++++++++++++++- dlls/msxml3/node.c | 5 +++-- dlls/msxml3/tests/domdoc.c | 25 ++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/dlls/msxml3/attribute.c b/dlls/msxml3/attribute.c index a183a504e66..41da38d6a3f 100644 --- a/dlls/msxml3/attribute.c +++ b/dlls/msxml3/attribute.c @@ -111,7 +111,7 @@ static ULONG WINAPI domattr_Release( if ( ref == 0 ) { destroy_xmlnode(&This->node); - if ( This->floating ) + if ( This->floating /*&& FALSE */) { xmlFreeNs( This->node.node->ns ); xmlFreeNode( This->node.node ); diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c index 3e3c2d06169..d3e4ab6ef6a 100644 --- a/dlls/msxml3/element.c +++ b/dlls/msxml3/element.c @@ -1641,7 +1641,40 @@ static HRESULT domelem_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMN return domelem_get_qualified_item(node, name, NULL, item);
/* try to get namespace uri for supplied qualified name */ - ns = xmlSearchNs(node->doc, node, prefix); + if (xmlStrEqual(prefix, BAD_CAST "xmlns") ) + { + IUnknown *unk; + xmlAttrPtr curr; + + xmlFree(prefix); + + ns = xmlSearchNs(node->doc, node, local); + xmlFree(local); + if (!ns) + { + if (item) *item = NULL; + return item ? S_FALSE : E_INVALIDARG; + } + + curr = xmlNewNsProp(NULL, NULL, ns->prefix, ns->href); + if (!curr) + { + return E_OUTOFMEMORY; + } + curr->doc = node->doc; + + unk = create_attribute((xmlNodePtr)curr, TRUE); + if (!unk) + { + xmlFreeProp(curr); + return E_OUTOFMEMORY; + } + hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)item); + IUnknown_Release(unk); + return hr; + } + else + ns = xmlSearchNs(node->doc, node, prefix);
xmlFree(prefix);
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index 5a3238edca8..b13b37b7bf4 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -1637,7 +1637,7 @@ HRESULT node_get_base_name(xmlnode *This, BSTR *name)
void destroy_xmlnode(xmlnode *This) { - if(This->node) + if(This->node /*&& This->node->type != 18*/) { xmlnode_release(This->node); xmldoc_release(This->node->doc); @@ -1646,7 +1646,7 @@ void destroy_xmlnode(xmlnode *This)
void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispex_static_data_t *dispex_data) { - if(node) + if(node /*&& node->type != 18*/) { xmlnode_add_ref(node); xmldoc_add_ref(node->doc); @@ -2237,6 +2237,7 @@ IXMLDOMNode *create_node( xmlNodePtr node ) case XML_ELEMENT_NODE: pUnk = create_element( node ); break; + //case 18: case XML_ATTRIBUTE_NODE: pUnk = create_attribute( node, FALSE ); break; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 175919b5169..ebedb17de39 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -10217,6 +10217,7 @@ static void test_get_attributes(void) IXMLDOMDocument *doc, *doc2; IXMLDOMNode *node, *node2; IXMLDOMElement *elem; + DOMNodeType type; VARIANT_BOOL b; HRESULT hr; VARIANT v; @@ -10256,7 +10257,6 @@ static void test_get_attributes(void) if (hr == S_OK && length == 1) { IXMLDOMAttribute *attr; - DOMNodeType type; VARIANT v;
node2 = NULL; @@ -10532,6 +10532,29 @@ static void test_get_attributes(void) IXMLDOMNode_Release(node2); }
+ hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_("xmlns:foaf"), &node2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + type = -1; + hr = IXMLDOMNode_get_nodeType(node2, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == NODE_ATTRIBUTE, "Unexpected type %d.\n", type); + IXMLDOMNode_Release(node2); + } + + hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_("dcterms:created"), &node2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + type = -1; + hr = IXMLDOMNode_get_nodeType(node2, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == NODE_ATTRIBUTE, "Unexpected type %d.\n", type); + IXMLDOMNode_Release(node2); + } + + IXMLDOMNamedNodeMap_Release(map); IXMLDOMElement_Release(elem);
Nikolay Sivov (@nsivov) commented about dlls/msxml3/element.c:
curr = xmlNewNsProp(NULL, NULL, ns->prefix, ns->href);
if (!curr)
{
return E_OUTOFMEMORY;
}
curr->doc = node->doc;
unk = create_attribute((xmlNodePtr)curr, TRUE);
if (!unk)
{
xmlFreeProp(curr);
return E_OUTOFMEMORY;
}
hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)item);
IUnknown_Release(unk);
return hr;
This doesn't look right. You are creating a new detached node every time. You can verify by getting this attribute, modifying its value, and then getting another reference from the same map. I'd expect updated value to be actually set in this case.
Also, please check for debugging changes - there are some commented lines that you don't need.