Nikolay Sivov : msxml3: Store namespace info for created attribute, fix returned properties.
Alexandre Julliard
julliard at winehq.org
Sat Jul 27 13:23:35 CDT 2013
Module: wine
Branch: master
Commit: 88e94c7ef8c2ea8a48d14397520724c1d897febc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=88e94c7ef8c2ea8a48d14397520724c1d897febc
Author: Nikolay Sivov <nsivov at 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();
More information about the wine-cvs
mailing list