diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c index 8c7d0d361cf..8a1496f5ea7 100644 --- a/dlls/msxml3/main.c +++ b/dlls/msxml3/main.c @@ -175,10 +175,18 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) case DLL_PROCESS_ATTACH: #ifdef HAVE_LIBXML2 xmlInitParser(); + + /* Set the default indent character to a single tab. */ + xmlThrDefTreeIndentString("\t"); #endif #ifdef HAVE_XSLTINIT xsltInit(); #endif + +#ifdef HAVE_LIBXML2 + /* Set the current ident to the default */ + xmlTreeIndentString = "\t"; +#endif hInstance = hInstDLL; DisableThreadLibraryCalls(hInstDLL); break; diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index 583e0e1c0a4..68bf8818a45 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -1039,6 +1039,59 @@ static HRESULT WINAPI xmlnode_put_dataType( return hr; } +static BSTR EnsureCorrectEOL(BSTR sInput) +{ + static const WCHAR SZ_RETURN[] = {'\n',0}; + static const WCHAR SZ_LINEFEED[] = {'\r',0}; + int nNum = 0; + BSTR sNew; + int nLen; + int i; + + nLen = lstrlenW(sInput); + /* Count line endings */ + for(i=0; i < nLen; i++) + { + if(sInput[i] == SZ_RETURN[0]) + nNum++; + } + + TRACE("len=%d, num=%d\n", nLen, nNum); + + /* Add linefeed as needed */ + if(nNum > 0) + { + int nPlace = 0; + sNew = SysAllocStringLen(NULL, nLen + nNum+1); + for(i=0; i < nLen; i++) + { + if(sInput[i] == SZ_RETURN[0]) + { + sNew[i+nPlace] = SZ_LINEFEED[0]; + nPlace++; + } + sNew[i+nPlace] = sInput[i]; + } + + SysFreeString(sInput); + } + else + { + sNew = sInput; + } + + TRACE("len %d\n", lstrlenW(sNew)); + + return sNew; +} + +/* + * We are trying to replicate the same behaviour as msxml by converting + * line endings to \r\n and using idents as \t. The problem is that msxml + * only formats nodes that have a line ending. Using libxml we cannot + * reproduce behaviour exactly. + * + */ static HRESULT WINAPI xmlnode_get_xml( IXMLDOMNode *iface, BSTR* xmlString) @@ -1047,7 +1100,7 @@ static HRESULT WINAPI xmlnode_get_xml( xmlBufferPtr pXmlBuf; int nSize; - TRACE("iface %p\n", iface); + TRACE("iface %p %d\n", iface, This->node->type); if(!xmlString) return E_INVALIDARG; @@ -1057,21 +1110,23 @@ static HRESULT WINAPI xmlnode_get_xml( pXmlBuf = xmlBufferCreate(); if(pXmlBuf) { - nSize = xmlNodeDump(pXmlBuf, This->node->doc, This->node, 0, 0); + nSize = xmlNodeDump(pXmlBuf, This->node->doc, This->node, 0, 1); if(nSize > 0) { const xmlChar *pContent; + BSTR bstrContent; /* Attribute Nodes return a space in front of their name */ pContent = xmlBufferContent(pXmlBuf); if( ((char*)pContent)[0] == ' ') - *xmlString = bstr_from_xmlChar(pContent+1); + bstrContent = bstr_from_xmlChar(pContent+1); else - *xmlString = bstr_from_xmlChar(pContent); + bstrContent = bstr_from_xmlChar(pContent); - - xmlBufferFree(pXmlBuf); + *xmlString = This->node->type == XML_ELEMENT_NODE ? EnsureCorrectEOL(bstrContent) : bstrContent; } + + xmlBufferFree(pXmlBuf); } /* Always returns a string. */ diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 1a2f85ca6a2..8d64804adc7 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -3419,6 +3419,44 @@ static void test_Namespaces(void) free_bstrs(); } +static void test_FormattingXML(void) +{ + IXMLDOMDocument2 *doc = NULL; + IXMLDOMElement *pElement; + VARIANT_BOOL bSucc; + HRESULT hr; + BSTR str; + static const CHAR szLinefeedXML[] = "\n\n\t\n"; + static const CHAR szLinefeedRootXML[] = "\r\n\t\r\n"; + + hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc ); + if( hr != S_OK ) + return; + + hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szLinefeedXML), &bSucc); + ok(hr == S_OK, "ret %08x\n", hr ); + ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n"); + + if(bSucc == VARIANT_TRUE) + { + hr = IXMLDOMDocument2_get_documentElement(doc, &pElement); + ok(hr == S_OK, "ret %08x\n", hr ); + if(hr == S_OK) + { + hr = IXMLDOMElement_get_xml(pElement, &str); + ok(hr == S_OK, "ret %08x\n", hr ); + ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n"); + SysFreeString(str); + + IXMLDOMElement_Release(pElement); + } + } + + IXMLDOMDocument2_Release(doc); + + free_bstrs(); +} + START_TEST(domdoc) { HRESULT r; @@ -3444,6 +3482,7 @@ START_TEST(domdoc) test_DocumentSaveToFile(); test_testTransforms(); test_Namespaces(); + test_FormattingXML(); CoUninitialize(); }