msxml3: Create additional node for xml declaration.

This commit is contained in:
Nikolay Sivov 2010-06-28 12:17:56 +04:00 committed by Alexandre Julliard
parent 5afe16621b
commit d461d7d213
4 changed files with 109 additions and 18 deletions

View File

@ -141,18 +141,75 @@ static xmldoc_priv * create_priv(void)
return priv;
}
/* links a "<?xml" node as a first child */
void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
{
assert(doc != NULL);
if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
}
/* unlinks a first "<?xml" child if it was created */
xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
{
xmlNodePtr node;
assert(doc != NULL);
if (doc->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 <?xml...?> */
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);

View File

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

View File

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

View File

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