Module: wine Branch: master Commit: 88e94c7ef8c2ea8a48d14397520724c1d897febc URL: http://source.winehq.org/git/wine.git/?a=commit;h=88e94c7ef8c2ea8a48d1439752...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Fri Jul 26 08:44:57 2013 +0400
msxml3: Store namespace info for created attribute, fix returned properties.
---
dlls/msxml3/attribute.c | 45 ++++++++++++++++++++- dlls/msxml3/domdoc.c | 23 +++++++++-- dlls/msxml3/tests/domdoc.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 6 deletions(-)
diff --git a/dlls/msxml3/attribute.c b/dlls/msxml3/attribute.c index 70dee2a..bb0655c 100644 --- a/dlls/msxml3/attribute.c +++ b/dlls/msxml3/attribute.c @@ -43,6 +43,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
#ifdef HAVE_LIBXML2
+static const xmlChar xmlns[] = "xmlns"; + typedef struct _domattr { xmlnode node; @@ -542,8 +544,29 @@ static HRESULT WINAPI domattr_get_namespaceURI( BSTR* p) { domattr *This = impl_from_IXMLDOMAttribute( iface ); + xmlNsPtr ns = This->node.node->ns; + TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); + + if (!p) + return E_INVALIDARG; + + *p = NULL; + + if (ns) + { + /* special case for default namespace definition */ + if (xmlStrEqual(This->node.node->name, xmlns)) + *p = bstr_from_xmlChar(xmlns); + else if (xmlStrEqual(ns->prefix, xmlns)) + *p = SysAllocStringLen(NULL, 0); + else if (ns->href) + *p = bstr_from_xmlChar(ns->href); + } + + TRACE("uri: %s\n", debugstr_w(*p)); + + return *p ? S_OK : S_FALSE; }
static HRESULT WINAPI domattr_get_prefix( @@ -551,8 +574,26 @@ static HRESULT WINAPI domattr_get_prefix( BSTR* prefix) { domattr *This = impl_from_IXMLDOMAttribute( iface ); + xmlNsPtr ns = This->node.node->ns; + TRACE("(%p)->(%p)\n", This, prefix); - return node_get_prefix( &This->node, prefix ); + + if (!prefix) return E_INVALIDARG; + + *prefix = NULL; + + if (ns) + { + /* special case for default namespace definition */ + if (xmlStrEqual(This->node.node->name, xmlns)) + *prefix = bstr_from_xmlChar(xmlns); + else if (ns->prefix) + *prefix = bstr_from_xmlChar(ns->prefix); + } + + TRACE("prefix: %s\n", debugstr_w(*prefix)); + + return *prefix ? S_OK : S_FALSE; }
static HRESULT WINAPI domattr_get_baseName( diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index 7eae2d4..a96b5c7 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -1934,9 +1934,6 @@ static HRESULT WINAPI domdoc_createNode( hr = get_node_type(Type, &node_type); if(FAILED(hr)) return hr;
- if(namespaceURI && namespaceURI[0] && node_type != NODE_ELEMENT) - FIXME("nodes with namespaces currently not supported.\n"); - TRACE("node_type %d\n", node_type);
/* exit earlier for types that need name */ @@ -1979,8 +1976,26 @@ static HRESULT WINAPI domdoc_createNode( break; } case NODE_ATTRIBUTE: - xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL); + { + xmlChar *local, *prefix; + + local = xmlSplitQName2(xml_name, &prefix); + + xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), local ? local : xml_name, NULL); + + if (local || (href && *href)) + { + /* we need a floating namespace here, it can't be created linked to attribute from + a start */ + xmlNsPtr ns = xmlNewNs(NULL, href, prefix); + xmlSetNs(xmlnode, ns); + } + + xmlFree(local); + xmlFree(prefix); + break; + } case NODE_TEXT: xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL); break; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 5f1b5c3..a32eda8 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -11590,6 +11590,99 @@ static void test_xsltext(void) free_bstrs(); }
+struct attrtest_t { + const char *name; + const char *uri; + const char *prefix; + const char *href; +}; + +static struct attrtest_t attrtests[] = { + { "xmlns", "http://www.w3.org/2000/xmlns/", "xmlns", "xmlns" }, + { "xmlns", "nondefaulturi", "xmlns", "xmlns" }, + { "c", "http://www.w3.org/2000/xmlns/", NULL, "http://www.w3.org/2000/xmlns/" }, + { "c", "nsref1", NULL, "nsref1" }, + { "ns:c", "nsref1", "ns", "nsref1" }, + { "xmlns:c", "http://www.w3.org/2000/xmlns/", "xmlns", "" }, + { "xmlns:c", "nondefaulturi", "xmlns", "" }, + { 0 } +}; + +static void test_create_attribute(void) +{ + struct attrtest_t *ptr = attrtests; + IXMLDOMElement *el; + IXMLDOMDocument *doc; + IXMLDOMNode *node, *node2; + VARIANT var; + HRESULT hr; + int i = 0; + BSTR str; + + doc = create_document(&IID_IXMLDOMDocument); + + while (ptr->name) + { + V_VT(&var) = VT_I1; + V_I1(&var) = NODE_ATTRIBUTE; + hr = IXMLDOMDocument_createNode(doc, var, _bstr_(ptr->name), _bstr_(ptr->uri), &node); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = NULL; + hr = IXMLDOMNode_get_prefix(node, &str); + if (ptr->prefix) + { + ok(hr == S_OK, "%d: got 0x%08x\n", i, hr); + ok(!lstrcmpW(str, _bstr_(ptr->prefix)), "%d: got prefix %s, expected %s\n", i, wine_dbgstr_w(str), ptr->prefix); + } + else + { + ok(hr == S_FALSE, "%d: got 0x%08x\n", i, hr); + ok(str == NULL, "%d: got prefix %s\n", i, wine_dbgstr_w(str)); + } + + str = NULL; + hr = IXMLDOMNode_get_namespaceURI(node, &str); + ok(hr == S_OK, "%d: got 0x%08x\n", i, hr); + ok(!lstrcmpW(str, _bstr_(ptr->href)), "%d: got uri %s, expected %s\n", i, wine_dbgstr_w(str), ptr->href); + SysFreeString(str); + + IXMLDOMNode_Release(node); + free_bstrs(); + + i++; + ptr++; + } + + V_VT(&var) = VT_I1; + V_I1(&var) = NODE_ELEMENT; + hr = IXMLDOMDocument_createNode(doc, var, _bstr_("e"), NULL, &node2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&el); + ok(hr == S_OK, "got 0x%08x\n", hr); + IXMLDOMNode_Release(node2); + + V_VT(&var) = VT_I1; + V_I1(&var) = NODE_ATTRIBUTE; + hr = IXMLDOMDocument_createNode(doc, var, _bstr_("xmlns:a"), _bstr_("http://www.w3.org/2000/xmlns/"), &node); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXMLDOMElement_setAttributeNode(el, (IXMLDOMAttribute*)node, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* for some reason default namespace uri is not reported */ + hr = IXMLDOMNode_get_namespaceURI(node, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, _bstr_("")), "got uri %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + IXMLDOMNode_Release(node); + IXMLDOMElement_Release(el); + IXMLDOMDocument_Release(doc); + free_bstrs(); +} + START_TEST(domdoc) { IXMLDOMDocument *doc; @@ -11644,6 +11737,7 @@ START_TEST(domdoc) test_setAttributeNode(); test_put_dataType(); test_createNode(); + test_create_attribute(); test_get_prefix(); test_default_properties(); test_selectSingleNode();