msxml3: Store namespace info for created attribute, fix returned properties.

This commit is contained in:
Nikolay Sivov 2013-07-26 08:44:57 +04:00 committed by Alexandre Julliard
parent d9211c9e5f
commit 88e94c7ef8
3 changed files with 156 additions and 6 deletions

View File

@ -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(

View File

@ -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;

View File

@ -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();