Nikolay Sivov : msxml3: Support elements with namespaces.
Alexandre Julliard
julliard at winehq.org
Tue Sep 14 17:35:25 CDT 2010
Module: wine
Branch: master
Commit: 8d055c78547cc3cb14df485b6c3bd4771c504445
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8d055c78547cc3cb14df485b6c3bd4771c504445
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue Sep 14 08:55:40 2010 +0400
msxml3: Support elements with namespaces.
---
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();
}
More information about the wine-cvs
mailing list