Даже мои 2 цента прибывают 7 лет спустя, я думаю, что вопрос все еще заслуживает простого ответа, заключенного в несколько строк кода, что возможно при использовании директивы #import
Visual C ++ и встроенной библиотеки поддержки C ++ COM (предлагая указатели и инкапсуляция обработки ошибок).
Обратите внимание, что, как и принятый ответ, он не пытается вписаться в класс CXml
, который использует OP, а скорее показывает основную идею. Также я предполагаю msxml6
.
Pretty-печать на любой поток
void PrettyWriteXmlDocument(MSXML2::IXMLDOMDocument* xmlDoc, IStream* stream)
{
MSXML2::IMXWriterPtr writer(__uuidof(MSXML2::MXXMLWriter60));
writer->encoding = L"utf-8";
writer->indent = _variant_t(true);
writer->standalone = _variant_t(true);
writer->output = stream;
MSXML2::ISAXXMLReaderPtr saxReader(__uuidof(MSXML2::SAXXMLReader60));
saxReader->putContentHandler(MSXML2::ISAXContentHandlerPtr(writer));
saxReader->putProperty(PUSHORT(L"http://xml.org/sax/properties/lexical-handler"), writer.GetInterfacePtr());
saxReader->parse(xmlDoc);
}
Поток файла
Если вам нужна потоковая запись в файл, вам нужна реализация интерфейса IStream
.
wtlext имеет класс, который вы можете использовать или из которого вы можете определить, как вы можете написать свой собственный.
Еще одно простое решение, которое мне пригодилось, - это использование класса Ado Stream:
void PrettySaveXmlDocument(MSXML2::IXMLDOMDocument* xmlDoc, const wchar_t* filePath)
{
ADODB::_StreamPtr stream(__uuidof(ADODB::Stream));
stream->Type = ADODB::adTypeBinary;
stream->Open(vtMissing, ADODB::adModeUnknown, ADODB::adOpenStreamUnspecified, _bstr_t(), _bstr_t());
PrettyWriteXmlDocument(xmlDoc, IStreamPtr(stream));
stream->SaveToFile(filePath, ADODB::adSaveCreateOverWrite);
}
Склеивание вместе
Упрощенная функция main
показывает это в действии:
#include <stdlib.h>
#include <objbase.h>
#include <comutil.h>
#include <comdef.h>
#include <comdefsp.h>
#import <msxml6.dll>
#import <msado60.tlb> rename("EOF", "EndOfFile") // requires: /I $(CommonProgramFiles)\System\ado
void PrettyWriteXmlDocument(MSXML2::IXMLDOMDocument* xmlDoc, IStream* stream);
void PrettySaveXmlDocument(MSXML2::IXMLDOMDocument* xmlDoc, const wchar_t* filePath);
int wmain()
{
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
try
{
MSXML2::IXMLDOMDocumentPtr xmlDoc(__uuidof(MSXML2::DOMDocument60));
xmlDoc->appendChild(xmlDoc->createElement(L"root"));
PrettySaveXmlDocument(xmlDoc, L"xmldoc.xml");
}
catch (const _com_error&)
{
}
CoUninitialize();
return EXIT_SUCCESS;
}
// assume definitions of PrettyWriteXmlDocument and PrettySaveXmlDocument go here