From 23269246c153a729ac5e4cb711897bf89df555c6 Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Tue, 18 Aug 2015 15:32:58 -0700 Subject: [PATCH] msxml3: treat namespace as attribute in IXMLDOMElement::getAttribute when getting the value of the attribute in this xml: msxml will return "uuid" for "xmlns:foo" and "attr b" for "foo:b". but Wine currently fails to return them, because libxml2 'eats' attributes that are namespace declarations, while msxml3 leaves them as attributes; libxml2 adds the 'foo' namespace with the href as "uuid" and does not add it as a property. the code change here is to search the namespace and use it to get the value of the property. "xmlns:" is a special case Signed-off-by: Daniel Lehman --- dlls/msxml3/element.c | 25 ++++++++++++++++++++++- dlls/msxml3/tests/domdoc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c index 38d3b47..6e00aa0 100644 --- a/dlls/msxml3/element.c +++ b/dlls/msxml3/element.c @@ -1203,7 +1203,9 @@ static HRESULT WINAPI domelem_getAttribute( domelem *This = impl_from_IXMLDOMElement( iface ); xmlNodePtr element; xmlChar *xml_name, *xml_value = NULL; + xmlChar *local, *prefix; HRESULT hr = S_FALSE; + xmlNsPtr ns; TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), value); @@ -1222,7 +1224,28 @@ static HRESULT WINAPI domelem_getAttribute( if(!xmlValidateNameValue(xml_name)) hr = E_FAIL; else - xml_value = xmlGetNsProp(element, xml_name, NULL); + { + if ((local = xmlSplitQName2(xml_name, &prefix))) + { + if (xmlStrEqual(prefix, BAD_CAST "xmlns")) + { + ns = xmlSearchNs(element->doc, element, local); + if (ns) + xml_value = xmlStrdup(ns->href); + } + else + { + ns = xmlSearchNs(element->doc, element, prefix); + if (ns) + xml_value = xmlGetNsProp(element, local, ns->href); + } + + xmlFree(prefix); + xmlFree(local); + } + else + xml_value = xmlGetNsProp(element, xml_name, NULL); + } heap_free(xml_name); if(xml_value) diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index ff6783b..1afc894 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -10882,6 +10882,56 @@ static void test_getAttributeNode(void) free_bstrs(); } +static void test_getAttribute(void) +{ + IXMLDOMDocument *doc; + IXMLDOMElement *elem; + VARIANT_BOOL v; + VARIANT var; + HRESULT hr; + + doc = create_document(&IID_IXMLDOMDocument); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + EXPECT_HR(hr, S_OK); + + VariantInit(&var); + hr = IXMLDOMElement_getAttribute( elem, _bstr_("xmlns:foo"), &var ); + EXPECT_HR(hr, S_OK); + ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var)); + ok( !lstrcmpW(V_BSTR(&var), _bstr_("urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); + + hr = IXMLDOMElement_getAttribute( elem, _bstr_("a"), &var ); + EXPECT_HR(hr, S_OK); + ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var)); + ok( !lstrcmpW(V_BSTR(&var), _bstr_("attr a")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); + + hr = IXMLDOMElement_getAttribute( elem, _bstr_("foo:b"), &var ); + EXPECT_HR(hr, S_OK); + ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var)); + ok( !lstrcmpW(V_BSTR(&var), _bstr_("attr b")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); + + hr = IXMLDOMElement_getAttribute( elem, _bstr_("b"), &var ); + EXPECT_HR(hr, S_FALSE); + ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var)); + VariantClear(&var); + + hr = IXMLDOMElement_getAttribute( elem, _bstr_("non-existent"), &var ); + EXPECT_HR(hr, S_FALSE); + ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var)); + VariantClear(&var); + + IXMLDOMElement_Release(elem); + IXMLDOMDocument_Release(doc); + free_bstrs(); +} + typedef struct { DOMNodeType type; const char *name; @@ -12071,6 +12121,7 @@ START_TEST(domdoc) test_dispex(); test_parseerror(); test_getAttributeNode(); + test_getAttribute(); test_supporterrorinfo(); test_nodeValue(); test_get_namespaces(); -- 1.9.5