TinyXML Read

C++용 XML 라이브러리가 몇가지 있다. MSXML 라이브러리, TinyXML 라이브러리가 있다.
작고 빠르다고 알려진 TinyXML 라비브러리를 알아 본다.

내가 사용한 버전은 TinyXML 2.5.3 버전이다. xmltet.cpp는 메모장에서 파일 인코딩을
UTF-8로 열고 유니코드 인코딩으로 재 저장하여 문자가 깨지지 않도록 한다.

TinyXML의 NodeType

TinyXml의 NodeType은 XML의 노드 타입과 대부분 비슷 하다.
XML 서적이나 문서를 보면 주석, 속성, TEXT, Element들의 최소단위는 노드이다.
엘리먼트와 노드를 혼동하지 않도록 한다.
TinyXML에서는 TiXmlElement노드가 TiXmlNode를 상속하고 있다.  

COMMENT 노드: 주석을 표현 하는 노드

ELEMENT 노드: 엘리먼트를 표현 하는 노이다.
              Test.xml에서는 root, food, name, country가 엘리먼트이다.
              (test.xml 파일은 아래에 나온다.)

TEXT 노드: 트리 구조상 최말단 노드로 문자 데이터를 표현하는 노드이다.

Attribute node: TinyXml 노드 타입에는 존재하지 않지만 TinyXml에서는 속성을 얻어                 올수 있는 메소드를 제공한다.

나머지 node 타입은 문서를 참고한다.

 

헤더 파일 포함

TinyXML 내부에서 자체 string 클래스 대신 std::string 클래스를 사용 할려면,
TIXML_USE_STL을 선언한다.
STL 사용에 필요한 헤더를 포함 시킨다.

#define TIXML_USE_STL    // TinyXML의 string대신 std::string을 사용할 경우.

#include “tinyxml.h”

 

#ifdef TIXML_USE_STL

    #include <iostream>

    #include <sstream>

    using namespace std;

#else

    #include <stdio.h>

#endif

 

라이브러리 링크

TIXML_USE_STL에 따라 라이브러리 링크를 다르게 설정한다.

//lib 파일 링크

 

#ifdef TIXML_USE_STL

 

#ifdef _DEBUG

#pragma comment(lib, "tinyxmld_STL")

#else

#pragma comment(lib, "tinyxml_STL")

#endif

 

#else

 

#ifdef _DEBUG

#pragma comment(lib, "tinyxmld")

#else

#pragma comment(lib, "tinyxml")

#endif

 

#endif

test.xml

읽을려는 XML 파일이다.

<?xml version="1.0" encoding="euc-kr"?>

<root>

  <!--각국의 대표 음식들이다.-->

  <food num="1">

      <name>김치</name>

      <country>대한민국</country>

  </food>

  <food num="2">

    <name>햄버그</name>

    <country>미국</country>

  </food> 

</root>

파일을 통해 읽을려면

    TiXmlDocument doc;

    doc.LoadFile("test.xml");

문자열을 통해 읽을려면

    TiXmlDocument doc;

    doc.Parse(szXML);

root 엘리먼트 노드를 읽는다.

TiXmlElement* rootElement = doc.FirstChildElement( "root" );

"root"의 자식 "food" 엘리먼트 노드를 읽는다.

    TiXmlElement*  element = doc.FirstChildElement( "root" )->FirstChildElement("food");

"food" 엘리먼트 노드를 반복해서 출력 한다.

    1     while( element )

    2     {

    3         //Value()는 현재 Node의 문자열을 넘겨준다.

    4         //GetText()는 현재 Text 타입 Node의 문자열을 넘겨 준다.

    5         //element->FirstChildElement()->Value()는 "name"을 넘겨준다.

    6         const char* num = element->Attribute( "num" );

    7         std::cout << "num Attribute: " << num << std::endl;

    8         std::cout << "name: " << element->FirstChildElement("name")->GetText() << std::endl;

    9         std::cout << "country: " << element->FirstChildElement("country")->GetText() << std::endl;

   10         element = element->NextSiblingElement( "food" );

   11     }

1: "food" 엘리먼트가 있을 때 까지 반복한다.

6: "num" 속성의 문자열을 읽어 온다.

속성을 정수로 읽을려면 다음과 같이 한다.
TiXmlAttribute* attr = element->FirstAttribute();
int n = attr->IntValue();

7: "name" 엘리먼트의 값을 읽는다.

8: "country" 엘리먼트의 값을 읽는다.

10: 다음 "food" 엘리먼트로 이동 한다.

 

XML 전체 파싱

ShowXML()은 XML을 파싱하여 보여주는 함수이다.
코드 설명은 생략....

void ShowXml(TiXmlNode *pNode)

{

       if(pNode)

       {

              switch(pNode->Type())

              {

              case TiXmlNode::COMMENT:

                    std::cout << "COMMENT: " << pNode->Value() << std::endl;

                    break;

              case TiXmlNode::DECLARATION:

                    std::cout << "DECLARATION: " << std::endl;

                    break;

 

              case TiXmlNode::ELEMENT:

                  {

                      std::cout << "ELEMENT: [" << pNode->ToElement()->Value() << "]" << std::endl;

                      TiXmlAttribute *pAttr = pNode->ToElement()->FirstAttribute();

                      while(pAttr)

                      {

                         std::cout << pAttr->Name() << "=\"" << pAttr->Value() << "\"" << std::endl;

                         pAttr = pAttr->Next();

                      }

                  }

                  break;

 

              case TiXmlNode::TEXT:

                   TiXmlText* pText = pNode->ToText();

                   if(pText)

                       std::cout << "TEXT:  " << pText->Value() << std::endl;

                   break;

              }

 

              for(TiXmlNode *pNext = pNode->FirstChild(); pNext; pNext = pNext->NextSibling())                     ShowXml(pNext);

       }

}

소스

tinyxml.zip

참조:

http://hanburn.tistory.com/7

http://hanburn.tistory.com/8