Nikolay Sivov : msxml3: Fix getNamedItem() for qualified node names.
Alexandre Julliard
julliard at winehq.org
Mon Nov 14 13:33:58 CST 2011
Module: wine
Branch: master
Commit: 02cd5a008f011fcd8a58b8346fb536d576227ffb
URL: http://source.winehq.org/git/wine.git/?a=commit;h=02cd5a008f011fcd8a58b8346fb536d576227ffb
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sat Nov 12 17:14:11 2011 +0300
msxml3: Fix getNamedItem() for qualified node names.
---
dlls/msxml3/nodemap.c | 42 +++++++++++++++-
dlls/msxml3/tests/domdoc.c | 110 +++++++++++++++++++++++++++++++++++++------
2 files changed, 133 insertions(+), 19 deletions(-)
diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c
index ebc2bd5..47adcd9 100644
--- a/dlls/msxml3/nodemap.c
+++ b/dlls/msxml3/nodemap.c
@@ -199,11 +199,47 @@ static HRESULT WINAPI xmlnodemap_Invoke(
static HRESULT WINAPI xmlnodemap_getNamedItem(
IXMLDOMNamedNodeMap *iface,
BSTR name,
- IXMLDOMNode** namedItem)
+ IXMLDOMNode** item)
{
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
- TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), namedItem );
- return IXMLDOMNamedNodeMap_getQualifiedItem(iface, name, NULL, namedItem);
+ xmlChar *nameA, *local, *prefix;
+ BSTR uriW, localW;
+ xmlNsPtr ns;
+ HRESULT hr;
+
+ TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), item );
+
+ nameA = xmlchar_from_wchar(name);
+ local = xmlSplitQName2(nameA, &prefix);
+ heap_free(nameA);
+
+ if (!local)
+ return IXMLDOMNamedNodeMap_getQualifiedItem(iface, name, NULL, item);
+
+ /* try to get namespace uri for supplied qualified name */
+ ns = xmlSearchNs(This->node->doc, This->node, prefix);
+
+ xmlFree(prefix);
+
+ if (!ns)
+ {
+ xmlFree(local);
+ if (item) *item = NULL;
+ return item ? S_FALSE : E_INVALIDARG;
+ }
+
+ uriW = bstr_from_xmlChar(ns->href);
+ localW = bstr_from_xmlChar(local);
+ xmlFree(local);
+
+ TRACE("got qualified node %s, uri=%s\n", debugstr_w(localW), debugstr_w(uriW));
+
+ hr = IXMLDOMNamedNodeMap_getQualifiedItem(iface, localW, uriW, item);
+
+ SysFreeString(localW);
+ SysFreeString(uriW);
+
+ return hr;
}
static HRESULT WINAPI xmlnodemap_setNamedItem(
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index affdfaa..a79da43 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -1746,6 +1746,12 @@ static const char* leading_spaces[] = {
0
};
+static const char default_ns_doc[] = {
+ "<?xml version=\"1.0\"?>"
+ "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
+ " d=\"d attr\" />"
+};
+
static const WCHAR szNonExistentFile[] = {
'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
};
@@ -7973,63 +7979,135 @@ static void test_splitText(void)
free_bstrs();
}
+typedef struct {
+ const char *name;
+ const char *uri;
+ HRESULT hr;
+} ns_item_t;
+
+/* default_ns_doc used */
+static const ns_item_t qualified_item_tests[] = {
+ { "xml:lang", NULL, S_FALSE },
+ { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
+ { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
+ { "ns:b", NULL, S_FALSE },
+ { "ns:b", "nshref", S_FALSE },
+ { "b", "nshref", S_OK },
+ { "d", NULL, S_OK },
+ { NULL }
+};
+
+static const ns_item_t named_item_tests[] = {
+ { "xml:lang", NULL, S_OK },
+ { "lang", NULL, S_FALSE },
+ { "ns:b", NULL, S_OK },
+ { "b", NULL, S_FALSE },
+ { "d", NULL, S_OK },
+ { NULL }
+};
+
static void test_getQualifiedItem(void)
{
- IXMLDOMDocument *doc;
- IXMLDOMElement *element;
IXMLDOMNode *pr_node, *node;
IXMLDOMNodeList *root_list;
IXMLDOMNamedNodeMap *map;
+ IXMLDOMElement *element;
+ const ns_item_t* ptr;
+ IXMLDOMDocument *doc;
VARIANT_BOOL b;
+ HRESULT hr;
BSTR str;
LONG len;
- HRESULT hr;
doc = create_document(&IID_IXMLDOMDocument);
if (!doc) return;
str = SysAllocString( szComplete4 );
hr = IXMLDOMDocument_loadXML( doc, str, &b );
- ok( hr == S_OK, "loadXML failed\n");
+ EXPECT_HR(hr, S_OK);
ok( b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString( str );
hr = IXMLDOMDocument_get_documentElement(doc, &element);
- ok( hr == S_OK, "ret %08x\n", hr);
+ EXPECT_HR(hr, S_OK);
hr = IXMLDOMElement_get_childNodes(element, &root_list);
- ok( hr == S_OK, "ret %08x\n", hr);
+ EXPECT_HR(hr, S_OK);
hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
- ok( hr == S_OK, "ret %08x\n", hr);
+ EXPECT_HR(hr, S_OK);
IXMLDOMNodeList_Release(root_list);
hr = IXMLDOMNode_get_attributes(pr_node, &map);
- ok( hr == S_OK, "ret %08x\n", hr);
+ EXPECT_HR(hr, S_OK);
IXMLDOMNode_Release(pr_node);
+ len = 0;
hr = IXMLDOMNamedNodeMap_get_length(map, &len);
- ok( hr == S_OK, "ret %08x\n", hr);
+ EXPECT_HR(hr, S_OK);
ok( len == 3, "length %d\n", len);
hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
- ok( hr == E_INVALIDARG, "ret %08x\n", hr);
+ EXPECT_HR(hr, E_INVALIDARG);
node = (void*)0xdeadbeef;
hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
- ok( hr == E_INVALIDARG, "ret %08x\n", hr);
+ EXPECT_HR(hr, E_INVALIDARG);
ok( node == (void*)0xdeadbeef, "got %p\n", node);
hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
- ok( hr == E_INVALIDARG, "ret %08x\n", hr);
+ EXPECT_HR(hr, E_INVALIDARG);
hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
- ok( hr == S_OK, "ret %08x\n", hr);
+ EXPECT_HR(hr, S_OK);
+
IXMLDOMNode_Release(node);
+ IXMLDOMNamedNodeMap_Release(map);
+ IXMLDOMElement_Release(element);
- IXMLDOMNamedNodeMap_Release( map );
- IXMLDOMElement_Release( element );
- IXMLDOMDocument_Release( doc );
+ hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
+ EXPECT_HR(hr, S_OK);
+ IXMLDOMNode_Release(node);
+
+ hr = IXMLDOMElement_get_attributes(element, &map);
+ EXPECT_HR(hr, S_OK);
+
+ ptr = qualified_item_tests;
+ while (ptr->name)
+ {
+ node = (void*)0xdeadbeef;
+ hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
+ ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
+ if (hr == S_OK)
+ IXMLDOMNode_Release(node);
+ else
+ ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
+ ptr++;
+ }
+
+ ptr = named_item_tests;
+ while (ptr->name)
+ {
+ node = (void*)0xdeadbeef;
+ hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
+ ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
+ if (hr == S_OK)
+ IXMLDOMNode_Release(node);
+ else
+ ok(node == NULL, "%s: got %p\n", ptr->name, node);
+ ptr++;
+ }
+
+ IXMLDOMNamedNodeMap_Release(map);
+
+ IXMLDOMElement_Release(element);
+ IXMLDOMDocument_Release(doc);
free_bstrs();
}
More information about the wine-cvs
mailing list