[PATCH] Make get_xml return a string consistent with msxml3
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Sat Jul 26 06:06:41 CDT 2008
---
dlls/msxml3/main.c | 8 +++++
dlls/msxml3/node.c | 71 +++++++++++++++++++++++++++++++++++++++-----
dlls/msxml3/tests/domdoc.c | 39 ++++++++++++++++++++++++
3 files changed, 110 insertions(+), 8 deletions(-)
diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c
index 8c7d0d3..4e61f19 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 583e0e1..c5838f9 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);
+ 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);
-
-
- xmlBufferFree(pXmlBuf);
+ bstrContent = bstr_from_xmlChar(pContent);
+
+ *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 1a2f85c..83c2d36 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[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
+ static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
+
+ 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();
}
--
1.5.4.1
--------------090504010708010004040105--
More information about the wine-patches
mailing list