지식을 담다2008/05/09 15:35
TinyXML : Simple C++ XML parser

<소개>

Documentaion :
http://www.grinninglizard.com/tinyxmldocs/index.html
Source : http://sourceforge.net/projects/tinyxml/

윈도우 버전 VC++6.0 프로젝트 포함
(STL 유/무 버전이 다름)

1. 해당 소스를 컴파일 하여 생성되는 Tinyxml.lib와 헤더파일을 이용하는 방법
   - 이방법은 제공되는 솔루션 파일( tinyxml.sln) 을 열어서 빌드만 하면 된다.
   - 사용하는 프로젝트가 멀티 쓰레드이면 런타임 라이브러리를 멀티 쓰레드로 변경해야 한다.
      (기본 설정은 싱글 쓰레드로 되어 있다.
   - tinyXml.lib 는 스태틱 라이브러리로 컴파일시에 exe에 포함되므로 따로 배포를 않해도 된다.

2. 소스를 직접 포함시켜서 사용하는 방법.
   - 필요한 파일을 프로젝트에 파일 추가로 등록한다.
      (tinystr.h(cpp), tinyxml.h(cpp), tinyxmlerror.cpp, tinyxmlparse.cpp 총 6개다 )
   - 컴파일을 하려고 하면 precompile header 관련하여 에러가 난다.
   - 프로젝트 설정에서 cpp의 (3개 파일) precompile header 사용을 빼버린면 된다.
User inserted image


<xml 읽기>

일단 XML을 파일에서 읽을수도 있고 문자열로 읽을 수도 있다.
아래 예에서 사용할 xml 파일은 다음과 같다.

<?xml version="1.0" ?>
<MyApp>
    <!-- Settings for MyApp -->
    <Messages>
        <Welcome>Welcome to MyApp</Welcome>
        <Farewell>Thank you for using MyApp</Farewell>
    </Messages>
    <Windows>
        <Window name="MainFrame" x="5" y="15" w="400" h="250" />
    </Windows>
    <Connection ip="192.168.0.1" timeout="123.456000" />
</MyApp>


먼저 파일에서 읽을때는,

TiXmlDocument document;
document.LoadFile(_File_Name_);


문자열로 읽을때는,

TiXmlDocument document;
document.Parse(szXML);


너무 쉽다. 그런 다음에는 원하는 값을 찾아오면 된다.
먼저 노드와 엘리먼트를 가지고 오는 방법을 알아보자.
( 노드는 자식을 가지고 있는 것이고 엘리먼트는 마지막에 있는 놈이다. )

TiXmlElement* pRoot = document.FirstChildElement("MyApp");
if( NULL == pRoot ) return FALSE;   // 해당 Element가 없으면 널이므로.. 체크해주는게 좋다.


그럼, <Welcome> 태그로 가서 데이터를 가지고 와보자.

pElement = pRoot->FirstChildElement("Message");
pElement = pElement->FirstChildElement("Welcome");
char* pAA = pElement->Value();                 // pAA 은  "Welcome" 이다.
pAA = pElement->GetText();                       // pAA 은  "Welcome to MyApp" 이다.


이번에는 다음에 windows 태그로 가서 name 속성을 읽어 와보자.

pElement = pRoot->FirstChildElement("Windows");
char* pAA = pElement->Attribute("name");   // pAA에 "MainFrame"이 들어온다.
int x;
pElement->Attribute("x", &x);                    // x 에 숫자 5가 들어온다.


그다음에는 루프를 돌면서 child 노드를 순환하는 방법이다.


pNode = pRoot->FirstChild("sub_node");
 for( pNode ; pNode ; pNode = pNode->NextSibling())
 {
  pAA = pNode->Value();  

  pElement = pNode->FirstChildElement("item");  
  pAA = pElement->GetText();
}


 

<xml 쓰기>

앞에서는 xml 파일이나 xml문자열에서 파싱을 해서 원하는 정보를 뽑아오는 것을 해보았다.
그러면 이제는 반대로 설정이나 원하는 정보를 xml 형식으로 만들어 보자.
앞에서 사용한 xml을 만들어 보도록 하자

<?xml version="1.0" ?>
<MyApp>
    <!-- Settings for MyApp -->
    <Messages>
        <Welcome>Welcome to MyApp</Welcome>
        <Farewell>Thank you for using MyApp</Farewell>
    </Messages>
    <Windows>
        <Window name="MainFrame" x="5" y="15" w="400" h="250" />
    </Windows>
    <Connection ip="192.168.0.1" timeout="123.456000" />
</MyApp>


일단 xml 의 형식선언부터 시작해 보자..

TiXmlDocument doc; 
TiXmlElement* msg;
TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); 
doc.LinkEndChild( decl );



이렇게 하면 <?xml version="1.0" ?> 이 생성된다.
다음으로는, 서브 노드를 추가해보자.

TiXmlElement * root = new TiXmlElement( "MyApp" ); 
doc.LinkEndChild( root ); 


간단하다. 그리고 new로 생성한 TiXmlElement를 해제할 필요가 없다. 내부에서 자동으로 삭제를 해주기 때문이다. (편리하군~ ^^)
그런 다음 주석문장을 추가해 보자.

TiXmlComment * comment = new TiXmlComment();
comment->SetValue(" Settings for MyApp " ); 
root->LinkEndChild( comment ); 


주석은 TiXmlComment 클래스를 사용하면 된다. 편리하군..
다음으로는  Message 서브노드와 하위 노드및 데이터를 추가해보자

TiXmlElement * msgs = new TiXmlElement( "Messages" ); 
root->LinkEndChild( msgs ); 

msg = new TiXmlElement( "Welcome" ); 
msg->LinkEndChild( new TiXmlText( "Welcome to MyApp" )); 
msgs->LinkEndChild( msg ); 

msg = new TiXmlElement( "Farewell" ); 
msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" )); 
msgs->LinkEndChild( msg ); 



역시 쉽니다. 다음에는 노드를 추가하고 Attribute를 설정해보자
레벨을 맞추기 위해서 root의 하위로 추가 한것을 주의 깊게 봐야 한다.

TiXmlElement * windows = new TiXmlElement( "Windows" ); 
root->LinkEndChild( windows ); 

TiXmlElement * window;
window = new TiXmlElement( "Window" ); 
windows->LinkEndChild( window ); 
window->SetAttribute("name", "MainFrame");
window->SetAttribute("x", 5);
window->SetAttribute("y", 15);
window->SetAttribute("w", 400);
window->SetAttribute("h", 250);



다음은 마지막으로 Double 값 (소수점 값) 을 설정하는 예를 보자

TiXmlElement * cxn = new TiXmlElement( "Connection" ); 
root->LinkEndChild( cxn ); 
cxn->SetAttribute("ip", "192.168.0.1");
cxn->SetDoubleAttribute("timeout", 123.456); // floating point attrib



이렇게 하면 우리가 원하는 xml이 doc에 만들어 졌다. 이것을 파일로 저장할 수도 있고 xml 문자열로 만들수도 있다. 방법은 아래를..

// 파일로 저장
doc.SaveFile("text.xml");

//문자열로..
TiXmlPrinter printer;
printer.SetStreamPrinting();
Doc.Accept( &printer );
char* pAA = printer.CStr();                    // char* 를 반환한다.
std::string str = printer.Str();                  // std::string으로 반환한다.


이로써 간단하게 TinyXML의 사용법을 마칠까 한다.

2008/05/09 15:35 2008/05/09 15:35
Posted by Haru

Trackback URL : http://blog.blog.jeongmin.net/trackback/123