[PATCH 1/4] Support elements with namespaces

Nikolay Sivov nsivov at codeweavers.com
Mon Sep 13 23:55:40 CDT 2010


---
 dlls/msxml3/domdoc.c       |   30 ++++++++++--
 dlls/msxml3/node.c         |   25 +++++-----
 dlls/msxml3/tests/domdoc.c |  107 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 142 insertions(+), 20 deletions(-)

diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index fe3aa4c..9053a7d 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -1468,19 +1468,19 @@ static HRESULT WINAPI domdoc_createNode(
     domdoc *This = impl_from_IXMLDOMDocument3( iface );
     DOMNodeType node_type;
     xmlNodePtr xmlnode;
-    xmlChar *xml_name;
+    xmlChar *xml_name, *href;
     HRESULT hr;
 
     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
 
     if(!node) return E_INVALIDARG;
 
-    if(namespaceURI && namespaceURI[0])
-        FIXME("nodes with namespaces currently not supported.\n");
-
     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 */
@@ -1496,12 +1496,31 @@ static HRESULT WINAPI domdoc_createNode(
     }
 
     xml_name = xmlChar_from_wchar(name);
+    /* prevent empty href to be allocated */
+    href = namespaceURI ? xmlChar_from_wchar(namespaceURI) : NULL;
 
     switch(node_type)
     {
     case NODE_ELEMENT:
-        xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
+    {
+        xmlChar *local, *prefix;
+
+        local = xmlSplitQName2(xml_name, &prefix);
+
+        xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL);
+
+        /* allow to create default namespace xmlns= */
+        if (local || (href && *href))
+        {
+            xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix);
+            xmlSetNs(xmlnode, ns);
+        }
+
+        xmlFree(local);
+        xmlFree(prefix);
+
         break;
+    }
     case NODE_ATTRIBUTE:
         xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
         break;
@@ -1543,6 +1562,7 @@ static HRESULT WINAPI domdoc_createNode(
 
     *node = create_node(xmlnode);
     heap_free(xml_name);
+    heap_free(href);
 
     if(*node)
     {
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index db894dd..e059d77 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -1098,35 +1098,34 @@ static HRESULT WINAPI xmlnode_put_dataType(
        lstrcmpiW(dataTypeName,szBinHex) == 0  ||
        lstrcmpiW(dataTypeName,szBinBase64) == 0)
     {
-        xmlNsPtr pNS = NULL;
-        xmlAttrPtr pAttr = NULL;
         xmlChar* str = xmlChar_from_wchar(dataTypeName);
+        xmlAttrPtr attr;
 
-        pAttr = xmlHasNsProp(This->node, (const xmlChar*)"dt",
+        if (!str) return E_OUTOFMEMORY;
+
+        attr = xmlHasNsProp(This->node, (const xmlChar*)"dt",
                             (const xmlChar*)"urn:schemas-microsoft-com:datatypes");
-        if (pAttr)
+        if (attr)
         {
-            pAttr = xmlSetNsProp(This->node, pAttr->ns, (const xmlChar*)"dt", str);
-
+            attr = xmlSetNsProp(This->node, attr->ns, (const xmlChar*)"dt", str);
             hr = S_OK;
         }
         else
         {
-            pNS = xmlNewNs(This->node, (const xmlChar*)"urn:schemas-microsoft-com:datatypes", (const xmlChar*)"dt");
-            if(pNS)
+            xmlNsPtr ns = xmlNewNs(This->node, (const xmlChar*)"urn:schemas-microsoft-com:datatypes", (const xmlChar*)"dt");
+            if (ns)
             {
-                pAttr = xmlNewNsProp(This->node, pNS, (const xmlChar*)"dt", str);
-                if(pAttr)
+                attr = xmlNewNsProp(This->node, ns, (const xmlChar*)"dt", str);
+                if (attr)
                 {
-                    xmlAddChild(This->node, (xmlNodePtr)pAttr);
-
+                    xmlAddChild(This->node, (xmlNodePtr)attr);
                     hr = S_OK;
                 }
                 else
                     ERR("Failed to create Attribute\n");
             }
             else
-                ERR("Failed to Create Namepsace\n");
+                ERR("Failed to create Namespace\n");
         }
         heap_free( str );
     }
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index a3ab55e..f65eff7 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -5910,7 +5910,7 @@ static void test_get_ownerDocument(void)
     if (!doc) return;
 
     str = SysAllocString( szComplete4 );
-    hr = IXMLDOMDocument2_loadXML( doc, str, &b );
+    hr = IXMLDOMDocument_loadXML( doc, str, &b );
     ok( hr == S_OK, "loadXML failed\n");
     ok( b == VARIANT_TRUE, "failed to load XML string\n");
     SysFreeString( str );
@@ -5976,7 +5976,7 @@ static void test_get_ownerDocument(void)
 
 static void test_setAttributeNode(void)
 {
-    IXMLDOMDocument *doc;
+    IXMLDOMDocument *doc, *doc2;
     IXMLDOMElement *elem;
     IXMLDOMAttribute *attr, *attr2, *ret_attr;
     VARIANT_BOOL b;
@@ -6019,8 +6019,109 @@ static void test_setAttributeNode(void)
     todo_wine ok( hr == E_FAIL, "got 0x%08x\n", hr);
     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
 
+    IXMLDOMElement_Release(elem);
+
+    /* add attribute already attached to another document */
+    doc2 = create_document(&IID_IXMLDOMDocument);
+
+    str = SysAllocString( szComplete4 );
+    hr = IXMLDOMDocument_loadXML( doc2, str, &b );
+    ok( hr == S_OK, "loadXML failed\n");
+    ok( b == VARIANT_TRUE, "failed to load XML string\n");
+    SysFreeString( str );
+
+    hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
+    todo_wine ok( hr == E_FAIL, "got 0x%08x\n", hr);
+    IXMLDOMElement_Release(elem);
+
+    IXMLDOMDocument_Release(doc2);
+
     IXMLDOMAttribute_Release(attr);
+    IXMLDOMDocument_Release(doc);
+    free_bstrs();
+}
+
+static void test_put_dataType(void)
+{
+    IXMLDOMCDATASection *cdata;
+    IXMLDOMDocument *doc;
+    VARIANT_BOOL b;
+    HRESULT hr;
+    BSTR str;
+
+    doc = create_document(&IID_IXMLDOMDocument);
+    if (!doc) return;
+
+    str = SysAllocString( szComplete4 );
+    hr = IXMLDOMDocument_loadXML( doc, str, &b );
+    ok( hr == S_OK, "loadXML failed\n");
+    ok( b == VARIANT_TRUE, "failed to load XML string\n");
+    SysFreeString( str );
+
+    hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("test"), &cdata);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("number"));
+    ok( hr == E_FAIL, "got 0x%08x\n", hr);
+    hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("string"));
+    ok( hr == E_FAIL, "got 0x%08x\n", hr);
+    IXMLDOMCDATASection_Release(cdata);
+
+    IXMLDOMDocument_Release(doc);
+    free_bstrs();
+}
+
+static void test_createNode(void)
+{
+    IXMLDOMDocument *doc;
+    IXMLDOMElement *elem;
+    IXMLDOMNode *node;
+    VARIANT v, var;
+    BSTR prefix, str;
+    HRESULT hr;
+
+    doc = create_document(&IID_IXMLDOMDocument);
+    if (!doc) return;
+
+    /* NODE_ELEMENT nodes */
+    /* 1. specified namespace */
+    V_VT(&v) = VT_I4;
+    V_I4(&v) = NODE_ELEMENT;
+
+    hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    prefix = NULL;
+    hr = IXMLDOMNode_get_prefix(node, &prefix);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
+    SysFreeString(prefix);
+    IXMLDOMNode_Release(node);
+
+    /* 2. default namespace */
+    hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    prefix = (void*)0xdeadbeef;
+    hr = IXMLDOMNode_get_prefix(node, &prefix);
+    todo_wine ok( hr == S_FALSE, "got 0x%08x\n", hr);
+    todo_wine ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
+
+    hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+
+    V_VT(&var) = VT_BSTR;
+    hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
+    ok( hr == S_FALSE, "got 0x%08x\n", hr);
+    ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
+
+    str = NULL;
+    hr = IXMLDOMElement_get_namespaceURI(elem, &str);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
+
     IXMLDOMElement_Release(elem);
+    IXMLDOMNode_Release(node);
+
     IXMLDOMDocument_Release(doc);
     free_bstrs();
 }
@@ -6079,6 +6180,8 @@ START_TEST(domdoc)
     test_removeQualifiedItem();
     test_get_ownerDocument();
     test_setAttributeNode();
+    test_put_dataType();
+    test_createNode();
 
     CoUninitialize();
 }
-- 
1.5.6.5



--------------030606090609050106030806--



More information about the wine-patches mailing list