[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