본문 바로가기

Application Programming Interface/Windows API

Visual C++로 MSXML 사용하기 #6

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

루트 엘리먼트, 자식 엘리먼트, 어트리뷰트, 텍스트 등 XML을 구성하는 기본적인 노드들을 VARIANT와 BSTR을 사용해 삽입해 보았습니다. 만든 XML 파일을 파일에 저장하는 방법은 XMLDOMDocument 클래스에 있는 save 메서드를 사용하면 됩니다. save 메서드는 매개변수로 VARIANT 형 구조체를 받습니다.

_bstr_t path = TEXT("test.xml");
_variant_t variant = path;
xmlDocument->save(variant);

이렇게 하면 프로그램이 실행되고 있는 위치에 test.xml을 생성하고 현재까지의 내용을 이 파일에 저장시킵니다.

제시된 XML대로 노드를 구성하고 파일로 저장해보겠습니다.

<?xml version="1.0"?>
<document string="tapito" float="3.14" double="3.14" integer="1318">
	<child>Hello, World!</child>
</document>

이를 코드로 작성하면

/* ex11.cpp */
#include <windows.h>
#include <stdio.h>
#include <locale.h>
#import <msxml4.dll>

int main(int argc, char * argv[])
{
	::setlocale(LC_ALL, "");

	if (SUCCEEDED(::CoInitialize(NULL)))
	{
		{
			_bstr_t bstr1, bstr2;
			_variant_t variant;
			IXMLDOMDocumentPtr xmlDocument;
			IXMLDOMProcessingInstructionPtr xmlProcessingInstruction;
			IXMLDOMElementPtr xmlElement1, xmlElement2;
			IXMLDOMAttributePtr xmlAttribute;

			if (!SUCCEEDED(xmlDocument.CreateInstance(__uuidof(DOMDocument))))
			{
				::wprintf(L"xmlDocument가 생성되지 않았습니다.\n");
				::CoUninitialize();
				return -1;
			}

			bstr1 = TEXT("xml");
			bstr2 = TEXT("version=\"1.0\"");
			xmlDocument->createProcessingInstruction(bstr1, bstr2, &xmlProcessingInstruction);

			xmlDocument->appendChild(xmlProcessingInstruction, NULL);

			/* <document string="tapito" float="3.14" double="1.59" integer="1318"> */
			bstr1 = TEXT("document");
			xmlDocument->createElement(bstr1, &xmlElement1);

			{
				bstr1 = TEXT("string");
				xmlDocument->createAttribute(bstr1, &xmlAttribute);
				bstr1 = TEXT("tapito");
				variant = bstr1;
				xmlAttribute->put_value(variant);
			}
			xmlElement1->setAttributeNode(xmlAttribute, NULL);

			{
				bstr1 = TEXT("float");
				xmlDocument->createAttribute(bstr1, &xmlAttribute);
				variant = 3.14f;
				xmlAttribute->put_value(variant);
			}
			xmlElement1->setAttributeNode(xmlAttribute, NULL);

			{
				bstr1 = TEXT("double");
				xmlDocument->createAttribute(bstr1, &xmlAttribute);
				variant = 3.14;
				xmlAttribute->put_value(variant);
			}
			xmlElement1->setAttributeNode(xmlAttribute, NULL);

			{
				bstr1 = TEXT("integer");
				xmlDocument->createAttribute(bstr1, &xmlAttribute);
				variant = 1318;
				xmlAttribute->put_value(variant);
			}
			xmlElement1->setAttributeNode(xmlAttribute, NULL);

			/* <child>Hello, World!</child> */
			bstr1 = TEXT("child");
			xmlDocument->createElement(bstr1, &xmlElement2);
			{
				bstr1 = TEXT("Hello, World!");
				xmlElement2->put_text(bstr1);
			}

			xmlDocument->appendChild(xmlElement1, NULL);
			xmlElement1->appendChild(xmlElement2, NULL);

			xmlDocument->get_xml(bstr1.GetAddress());
			::wprintf(L"%s", (const wchar_t *)bstr1);

			/* 저장하기 */
			bstr1 = TEXT("test.xml");
			variant = bstr1;
			xmlDocument->save(variant);

			::wprintf(L"saved.");
		}
		::CoUninitialize();
	}
	return 0;
}

실행 결과 test.xml 파일이 생성되었습니다. 브라우저로 열어보면 콘솔에 출력된 것과 같은 XML을 확인할 수 있습니다.