MSXML の SAXWriter
Domを使って書き込むのではなく、SAXで何か良いのはないかと思っていたら
MSXMLに IMXWriter という SAXWriter があるではないか。
今のコードは Windows 限定だし使ってみるかーということでトライ。
// saxwritertest.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "windows.h" #include "Objbase.h" #import <msxml6.dll> named_guids #include <iostream> #include <vector> namespace { bool CreateStream( IStream** stream ) { HRESULT hr = ::CreateStreamOnHGlobal( NULL, TRUE, stream ); return hr == S_OK; } } // namespace int _tmain(int argc, _TCHAR* argv[]) { ::CoInitialize( NULL ); IStreamPtr stream; CreateStream( &stream.GetInterfacePtr() ); try { MSXML2::IMXWriterPtr writer; HRESULT hr = writer.CreateInstance( MSXML2::CLSID_MXXMLWriter60 ); writer->byteOrderMark = VARIANT_TRUE; writer->encoding = _bstr_t( "utf-8" ); writer->indent = VARIANT_TRUE; writer->output = stream.GetInterfacePtr(); MSXML2::ISAXContentHandlerPtr handler = writer; handler->startDocument(); wchar_t* ns( L"test" ); wchar_t* local( L"example" ); wchar_t* qname( L"test:example" ); handler->startElement( reinterpret_cast<unsigned short*>( ns ), wcslen( ns ), reinterpret_cast<unsigned short*>( local ), wcslen( local ), reinterpret_cast<unsigned short*>( qname ), wcslen( qname ), NULL ); handler->endElement( reinterpret_cast<unsigned short*>( ns ), wcslen( ns ), reinterpret_cast<unsigned short*>( local ), wcslen( local ), reinterpret_cast<unsigned short*>( qname ), wcslen( qname ) ); handler->endDocument(); }catch(_com_error& e ){ std::cout << e.ErrorMessage() << std::endl; ::CoUninitialize(); return 0; } { // 書き込み内容を見る LARGE_INTEGER pos = {0, 0}; stream->Seek( pos, STREAM_SEEK_SET, NULL ); size_t size( 1024 ); std::vector<byte> buffer; buffer.resize( size, 0 ); unsigned long read; stream->Read( &buffer[0], size, &read ); std::cout << &buffer[0] << std::endl; } ::CoUninitialize(); return 0; }
で結果が
<?xml version="1.0" encoding="utf-8" standalone="no"?> <test:example/> 続行するには何かキーを押してください . . .
・・・おーい? xmlns が出てないよ?
と思ってネットを探っていたら バグです とか・・・
あきらめて、litexml とか xerces とか libxml とか使いましょ!