Этот может быть хорошим постом для вашего рассмотрения.
Открытие файла в режиме w
перезапишет файл, а это означает, что, если вы потом ничего не записываете в файл, он фактически очистит содержимое файла - в вашем случае без дополнительного текста, оставив содержимое файла пустым.
Попробуйте это, я нашел это несколько лет назад в сети.
#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)));
}
Вот измененная версия принятого ответа, который преобразует в оперативной памяти (изменяется только в последних нескольких строках, но я отправляю целый блок для удобства будущих читателей):
bool CXml::FormatDOMDocument(IXMLDOMDocument *pDoc)
{
// 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
bool success1 = SUCCEEDED(pMXWriter->put_output(CComVariant(pDoc.GetInterfacePtr())));
bool success2 = SUCCEEDED(pSAXReader->parse(CComVariant(pDoc.GetInterfacePtr())));
return success1 && success2;
}
Если библиотека не имеет параметр формата затем, единственный другой путь состоит в том, чтобы использовать XSLT или внешний симпатичный принтер (я думаю, что htmltidy может также сделать xml), Там doen't, кажется, опция в codeproject lib, но можно указать таблицу стилей XSLT к MSXML.
Я записал sed сценарий некоторое время назад для основного расположения с отступом xml. Можно использовать его в качестве внешнего индентера, если все остальное перестало работать (сохраните это к xmlindent.sed и обработайте xml с sed-f xmlindent.sed <имя файла>). Вам, возможно, понадобились бы cygwin или некоторая другая posix среда для использования его все же.
Вот источник:
:a
/>/!N;s/\n/ /;ta
s/ / /g;s/^ *//;s/ */ /g
/^<!--/{
:e
/-->/!N;s/\n//;te
s/-->/\n/;D;
}
/^<[?!][^>]*>/{
H;x;s/\n//;s/>.*$/>/;p;bb
}
/^<\/[^>]*>/{
H;x;s/\n//;s/>.*$/>/;s/^ //;p;bb
}
/^<[^>]*\/>/{
H;x;s/\n//;s/>.*$/>/;p;bb
}
/^<[^>]*[^\/]>/{
H;x;s/\n//;s/>.*$/>/;p;s/^/ /;bb
}
/</!ba
{
H;x;s/\n//;s/ *<.*$//;p;s/[^ ].*$//;x;s/^[^<]*//;ba
}
:b
{
s/[^ ].*$//;x;s/^<[^>]*>//;ba
}
Hrmp, вкладки, кажется, искажены... Вы можете отходы копии отсюда вместо этого: XML, делающий отступ с sed (1)