From d461d7d2136fcb8fa591784742c31237ad5b10d6 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 28 Jun 2010 12:17:56 +0400 Subject: [PATCH] msxml3: Create additional node for xml declaration. --- dlls/msxml3/domdoc.c | 71 +++++++++++++++++++++++++++++++++++++++++---- dlls/msxml3/msxml_private.h | 2 ++ dlls/msxml3/node.c | 5 ++++ dlls/msxml3/tests/domdoc.c | 49 ++++++++++++++++++++++--------- 4 files changed, 109 insertions(+), 18 deletions(-) diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index 54e4728f58a..cec59e81e03 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -141,18 +141,75 @@ static xmldoc_priv * create_priv(void) return priv; } +/* links a "standalone != -1) xmlAddPrevSibling( doc->children, node ); +} + +/* unlinks a first "standalone != -1) + { + node = doc->children; + xmlUnlinkNode( node ); + } + else + node = NULL; + + return node; +} + static xmlDocPtr doparse( char *ptr, int len, const char *encoding ) { + xmlDocPtr doc; + #ifdef HAVE_XMLREADMEMORY /* * use xmlReadMemory if possible so we can suppress * writing errors to stderr */ - return xmlReadMemory( ptr, len, NULL, encoding, - XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS ); + doc = xmlReadMemory( ptr, len, NULL, encoding, + XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS ); #else - return xmlParseMemory( ptr, len ); + doc = xmlParseMemory( ptr, len ); #endif + + /* create first child as a */ + if (doc && doc->standalone != -1) + { + xmlNodePtr node; + char buff[30]; + xmlChar *xmlbuff = (xmlChar*)buff; + + node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL ); + + /* version attribute can't be omitted */ + sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0"); + xmlNodeAddContent( node, xmlbuff ); + + if (doc->encoding) + { + sprintf(buff, " encoding=\"%s\"", doc->encoding); + xmlNodeAddContent( node, xmlbuff ); + } + + if (doc->standalone != -2) + { + sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes"); + xmlNodeAddContent( node, xmlbuff ); + } + + xmldoc_link_xmldecl( doc, node ); + } + + return doc; } LONG xmldoc_add_ref(xmlDocPtr doc) @@ -345,7 +402,7 @@ static HRESULT WINAPI xmldoc_IPersistStream_Load( len = GlobalSize(hglobal); ptr = GlobalLock(hglobal); if (len != 0) - xmldoc = parse_xml(ptr, len); + xmldoc = doparse(ptr, len, NULL); GlobalUnlock(hglobal); if (!xmldoc) @@ -1524,7 +1581,7 @@ static HRESULT WINAPI domdoc_load( { *isSuccessful = VARIANT_TRUE; - TRACE("Using ID_IStream to load Document\n"); + TRACE("Using IStream to load Document\n"); return S_OK; } else @@ -1733,6 +1790,7 @@ static HRESULT WINAPI domdoc_save( domdoc *This = impl_from_IXMLDOMDocument2( iface ); HANDLE handle; xmlSaveCtxtPtr ctx; + xmlNodePtr xmldecl; HRESULT ret = S_OK; TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination), @@ -1788,7 +1846,10 @@ static HRESULT WINAPI domdoc_save( return S_FALSE; } + xmldecl = xmldoc_unlink_xmldecl(get_doc(This)); if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE; + xmldoc_link_xmldecl(get_doc(This), xmldecl); + /* will close file through close callback */ xmlSaveClose(ctx); diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 1df3e8b6cd5..e0279f11516 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -134,6 +134,8 @@ extern LONG xmldoc_add_ref( xmlDocPtr doc ); extern LONG xmldoc_release( xmlDocPtr doc ); extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node ); extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node ); +extern void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node); +extern xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc); extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj, BOOL own ); diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index 135844ff1fd..bbdcb5d0ff2 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -1382,6 +1382,7 @@ static HRESULT WINAPI xmlnode_get_xml( { xmlnode *This = impl_from_IXMLDOMNode( iface ); xmlBufferPtr pXmlBuf; + xmlNodePtr xmldecl; int nSize; TRACE("(%p %d)->(%p)\n", This, This->node->type, xmlString); @@ -1391,6 +1392,8 @@ static HRESULT WINAPI xmlnode_get_xml( *xmlString = NULL; + xmldecl = xmldoc_unlink_xmldecl( This->node->doc ); + pXmlBuf = xmlBufferCreate(); if(pXmlBuf) { @@ -1424,6 +1427,8 @@ static HRESULT WINAPI xmlnode_get_xml( xmlBufferFree(pXmlBuf); } + xmldoc_link_xmldecl( This->node->doc, xmldecl ); + /* Always returns a string. */ if(*xmlString == NULL) *xmlString = SysAllocStringLen( NULL, 0 ); diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 9c1440cffaa..cde4c81ae3f 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -470,20 +470,8 @@ static void node_to_string(IXMLDOMNode *node, char *buf) } else { - int pos = get_node_position(node); - DOMNodeType parent_type = NODE_INVALID; r = IXMLDOMNode_get_parentNode(node, &new_node); - - /* currently wine doesn't create a node for the . To be able to test query - * results we "fix" it */ - if (r == S_OK) - ole_check(IXMLDOMNode_get_nodeType(new_node, &parent_type)); - if ((parent_type == NODE_DOCUMENT) && type != NODE_PROCESSING_INSTRUCTION && pos==1) - { - todo_wine ok(FALSE, "The first child of the document node in MSXML is the processing instruction\n"); - pos++; - } - wsprintf(buf, "%d", pos); + wsprintf(buf, "%d", get_node_position(node)); buf += strlen(buf); } @@ -2477,6 +2465,40 @@ static void test_get_childNodes(void) IXMLDOMDocument_Release( doc ); } +static void test_get_firstChild(void) +{ + static WCHAR xmlW[] = {'x','m','l',0}; + IXMLDOMDocument *doc; + IXMLDOMNode *node; + VARIANT_BOOL b; + HRESULT r; + BSTR str; + + r = CoCreateInstance( &CLSID_DOMDocument, NULL, + CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc ); + ok( r == S_OK, "failed with 0x%08x\n", r ); + if( r != S_OK ) + return; + + str = SysAllocString( szComplete4 ); + r = IXMLDOMDocument_loadXML( doc, str, &b ); + ok( r == S_OK, "loadXML failed\n"); + ok( b == VARIANT_TRUE, "failed to load XML string\n"); + SysFreeString( str ); + + r = IXMLDOMDocument_get_firstChild( doc, &node ); + ok( r == S_OK, "ret %08x\n", r); + + r = IXMLDOMNode_get_nodeName( node, &str ); + ok( r == S_OK, "ret %08x\n", r); + + ok(memcmp(str, xmlW, sizeof(xmlW)) == 0, "expected \"xml\" node name\n"); + + SysFreeString(str); + IXMLDOMNode_Release( node ); + IXMLDOMDocument_Release( doc ); +} + static void test_removeChild(void) { HRESULT r; @@ -5581,6 +5603,7 @@ START_TEST(domdoc) test_getElementsByTagName(); test_get_text(); test_get_childNodes(); + test_get_firstChild(); test_removeChild(); test_replaceChild(); test_removeNamedItem(); -- 2.11.4.GIT