Search code examples
xmlmsxmlpretty-print

MSXML from C++ - pretty print / indent newly created documents


I'm writing out XML files using the MSXML parser, with a wrapper I downloaded from here: http://www.codeproject.com/KB/XML/JW_CXml.aspx. Works great except that when I create a new document from code (so not load from file and modify), the result is all in one big line. I'd like elements to be indented nicely so that I can read it easily in a text editor.

Googling shows many people with the same question - asked around 2001 or so. Replies usually say 'apply an XSL transformation' or 'add your own whitespace nodes'. Especially the last one makes me go %( so I'm hoping that in 2008 there's an easier way to pretty MSXML output. So my question; is there, and how do I use it?


Solution

  • Try this, I found this years ago on the web.

    #include <msxml2.h>
    
    bool FormatDOMDocument (IXMLDOMDocument *pDoc, IStream *pStream)
    {
    
        // Create the writer
    
        CComPtr <IMXWriter> pMXWriter;
        if (FAILED (pMXWriter.CoCreateInstance(__uuidof (MXXMLWriter), NULL, CLSCTX_ALL)))
        {
            return false;
        }
        CComPtr <ISAXContentHandler> pISAXContentHandler;
        if (FAILED (pMXWriter.QueryInterface(&pISAXContentHandler)))
        {
            return false;
        }
        CComPtr <ISAXErrorHandler> pISAXErrorHandler;
        if (FAILED (pMXWriter.QueryInterface (&pISAXErrorHandler)))
        {
            return false;
        }
        CComPtr <ISAXDTDHandler> pISAXDTDHandler;
        if (FAILED (pMXWriter.QueryInterface (&pISAXDTDHandler)))
        {
            return false;
        }
    
        if (FAILED (pMXWriter ->put_omitXMLDeclaration (VARIANT_FALSE)) ||
            FAILED (pMXWriter ->put_standalone (VARIANT_TRUE)) ||
            FAILED (pMXWriter ->put_indent (VARIANT_TRUE)) ||
            FAILED (pMXWriter ->put_encoding (L"UTF-8")))
        {
            return false;
        }
    
        // Create the SAX reader
    
        CComPtr <ISAXXMLReader> pSAXReader;
        if (FAILED (pSAXReader.CoCreateInstance (__uuidof (SAXXMLReader), NULL, CLSCTX_ALL)))
        {
            return false;
        }
    
        if (FAILED (pSAXReader ->putContentHandler (pISAXContentHandler)) ||
            FAILED (pSAXReader ->putDTDHandler (pISAXDTDHandler)) ||
            FAILED (pSAXReader ->putErrorHandler (pISAXErrorHandler)) ||
            FAILED (pSAXReader ->putProperty (
            L"http://xml.org/sax/properties/lexical-handler", CComVariant (pMXWriter))) ||
            FAILED (pSAXReader ->putProperty (
            L"http://xml.org/sax/properties/declaration-handler", CComVariant (pMXWriter))))
        {
            return false;
        }
    
        // Perform the write
    
        return 
           SUCCEEDED (pMXWriter ->put_output (CComVariant (pStream))) &&
           SUCCEEDED (pSAXReader ->parse (CComVariant (pDoc)));
    }