심플하고 강력한 MFC,C++ 용 XML 파서(CMarkup)

2021. 1. 5. 20:37장비제어개발관한이야기

반응형

개발자의 책상의 모습
내 책생

 

 

자료도 소장할겸, 여러가지 겸사겸사 블로그를 시작하였습니다. 많이 모르지만 도움이 되었으면합니다.

 

 

파라미터의 저장 과 읽기

 

MFC 기반 장비제어를 하면서 위치정보 각종 파라미터 저장시에는 저희 회사 전통적으로 기본적인 파일입출력(바이너리)을 사용하였습니다.

그러나 파일입출력의 경우 가독성이 제로에 가깝고 수시로 바뀌는 파라미터가 감당이 안되서 마크업기반 언어인 XML 사용하기로 결정 하였습니다. 개발자가 혼자라서 뭐 결정이라고 할 것도 없네요.

 

XML 기반 라이브러리를 여러가지 찾아 보았습니다.   에서 심플하고 속도에서 강점을 내세우면서 STL 만을 사용하여 플랫폼 이식에도 뛰어난 오픈소스를 찾았습니다.노드당 최대 4Gbyte 정보를 저장하게 되면 뻗어버리는(?) 단점만 빼고 훌륭한 라이브러리였습니다.

그리고 MSXML 다르게 문법검사시에 Exception 발생도 안되고 기존 C++ 코딩 스타일을 유지할수 있었기에 더욱더 마음에 드는  C++ 용  XML 파서였습니다.

 

그리고 한가지 주의할 사항은  CMarkup 기본적은로 Cstring 클래스를 사용하게 되어있어서 MFC 이외에서 사용하려면 전처리에서 MARUP_STL 정의 해줘야 합니다. 물론 저는 MFC 기반 장비제어를 주로 하기에 상관은 없습니다.

 

추후, CMarkup 을 대신할수 있게 파서는 교체 가능하게 유연성도 필요할 것으로 보입니다.

  

 

CMarkUp 사용예제 및 소스코드

void TestCMarkUp()
{
     CMarkup xml;

     xml.AddElem(_T("Machine"));             // 현재 Level 수준에서 Element를 추가합니다.
     xml.AddChildElem(_T("MachineSize"));    // 현재 Level 에서 Element를 Child로 추가합니다.

     xml.IntoElem();                         // 한단계 안으로 들어갑니다.
     xml.AddAttrib(_T("XSIZE"),_T("200"));   // 현재 Element에 Attribute 를 추가합니다.
     xml.AddAttrib(_T("YSIZE"),_T("200"));   //IntoElem 후 AddAttrib 는 AddChildAttrib 같음
     xml.OutOfElem();                        // 현재 Level에서(Machine) 나옵니다.

     xml.AddElem(_T("X"));
     xml.AddChildElem(_T("COL"));
     xml.IntoElem();
     xml.AddAttrib(_T("Count"),_T("3"));
     xml.AddChildElem(_T("Data"),_T("4")); // IntoElem 후 AddElem 와 똑같은 효과를 냅니다.
     xml.AddChildElem(_T("Data"),_T("7"));
     xml.AddChildElem(_T("Data"),_T("2"));
     xml.OutOfElem();

     CString strXML = xml.GetDoc();
     AfxMessageBox(strXML);
     
     xml.Save(_T("TestXml.XML"));
}
 

그러면 실행경로에 다음과 같이 TestXml.XML이 생성됩니다.

[실행파일 내용]
<Machine>
<MachineSize XSIZE="200" YSIZE="200"/>
</Machine>
<X>
<COL Count="3">
<Data>4</Data>
<Data>7</Data>
<Data>2</Data>
</COL>
</X>

 

 

파일을 썼으니 로드를 해보겠습니다.

void TestCMarkupToLoad()
{
    CMarkup xml;
    CString strFileName = _T("TestXml.XML");
    if (xml.Load(strFileName) == true)
    {
        return;
    }

    bool b1 = xml.FindElem(_T("Machine"));  //Element 를 찾습니다.
    bool b2 = xml.IntoElem();
    bool b3 = xml.FindElem(_T("MachineSize"));
    CString strSizeX = xml.GetAttrib(_T("SIZEX")); // 현재 Element에서 Attribute 의 값을 가져옵니다.
    CString strSizeY = xml.GetAttrib(_T("SIZEY"));

    CString strMsg;
    strMsg.Format(_T("SIZEX : %s, SIZEY: %s"),strSizeX,strSizeY);
    AfxMessageBox(strMsg);

    bool b4 = xml.OutOfElem();
    bool b5 = xml.FindElem(_T("X"));
    bool b6 = xml.IntoElem();
    bool b7 = xml.FindElem(_T("COL"));
    int nCountX = _wtoi(xml.GetAttrib(_T("Count")));
    CString strCountX = xml.GetAttrib(_T("Count"));

    strMsg.Format(_T("nCOuntX : %d, strCountX: %s"),nCountX,strCountX);
    AfxMessageBox(strMsg);
    
    bool b8 = xml.IntoElem();
    while(xml.FindElem(_T("Data")))
    {
        AfxMessageBox(xml.GetData());
    }
    bool b9 = xml.OutOfElem();
    bool b10 = xml.OutOfElem();
}

 

 

 

 

 

파일첨부

Markup115.zip
다운로드

 

 

 

 

 

 

반응형