msxml3: Use libxml2 functionality to skip top XML declaration node while writing to file.
This commit is contained in:
parent
ecb2d7bd93
commit
afad45fffe
|
@ -47,6 +47,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
|||
|
||||
#ifdef HAVE_LIBXML2
|
||||
|
||||
#include <libxml/xmlsave.h>
|
||||
|
||||
static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
|
||||
static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
|
||||
static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
|
||||
|
@ -1651,6 +1653,24 @@ static HRESULT WINAPI domdoc_loadXML(
|
|||
return hr;
|
||||
}
|
||||
|
||||
static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
|
||||
int len)
|
||||
{
|
||||
DWORD written = -1;
|
||||
|
||||
if(!WriteFile(ctx, buffer, len, &written, NULL))
|
||||
{
|
||||
WARN("write error\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return written;
|
||||
}
|
||||
|
||||
static int XMLCALL domdoc_save_closecallback(void *ctx)
|
||||
{
|
||||
return CloseHandle(ctx) ? 0 : -1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI domdoc_save(
|
||||
IXMLDOMDocument2 *iface,
|
||||
|
@ -1658,10 +1678,8 @@ static HRESULT WINAPI domdoc_save(
|
|||
{
|
||||
domdoc *This = impl_from_IXMLDOMDocument2( iface );
|
||||
HANDLE handle;
|
||||
xmlChar *mem, *p;
|
||||
int size;
|
||||
xmlSaveCtxtPtr ctx;
|
||||
HRESULT ret = S_OK;
|
||||
DWORD written;
|
||||
|
||||
TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
|
||||
V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
|
||||
|
@ -1707,31 +1725,19 @@ static HRESULT WINAPI domdoc_save(
|
|||
return S_FALSE;
|
||||
}
|
||||
|
||||
xmlDocDumpMemory(get_doc(This), &mem, &size);
|
||||
|
||||
/*
|
||||
* libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
|
||||
* MSXML adds XML declaration only for processing instruction nodes.
|
||||
* We skip the first XML declaration generated by libxml2 to get exactly what we need.
|
||||
*/
|
||||
p = mem;
|
||||
if(size > 2 && p[0] == '<' && p[1] == '?') {
|
||||
while(p < mem+size && (p[0] != '?' || p[1] != '>'))
|
||||
p++;
|
||||
p += 2;
|
||||
while(p < mem+size && isspace(*p))
|
||||
p++;
|
||||
size -= p-mem;
|
||||
}
|
||||
|
||||
if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
|
||||
/* disable top XML declaration */
|
||||
ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
|
||||
handle, NULL, XML_SAVE_NO_DECL);
|
||||
if (!ctx)
|
||||
{
|
||||
WARN("write error\n");
|
||||
ret = S_FALSE;
|
||||
CloseHandle(handle);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
xmlFree(mem);
|
||||
CloseHandle(handle);
|
||||
if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
|
||||
/* will close file through close callback */
|
||||
xmlSaveClose(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue