기본 콘텐츠로 건너뛰기

윈도우에서 오라클19c 설치 중 ins-35180 오류 발생 시 조치 방법

RapidXml에서 문자열 파싱하기 및 주의사항

C++에서 XML 파싱에 사용하는 라이브러리 중 RapidXml이 있습니다.
속도가 빠르고, 헤더 파일로만 되어 있어서 단순히 파일을 복사하는 정도만으로 쉽게 사용할 수 있다는 장점이 있습니다.
더군다나 MIT 라이선스로 사용 가능하므로 상업용 프로그램에도 유용하게 사용할 수 있습니다.

공식 사이트: http://rapidxml.sourceforge.net

그런데 주의사항이 있습니다.
우선 아래를 봐주시기 바랍니다.
string strXml = "<?xml version="1.0" encoding="utf-8"?><books>  ... (중략) ...  </books>";

xml_document<> doc;
doc.parse<0>((char*)strXml.c_str());
xml_node<>* root =  doc.first_node();
printf("root 노드 이름: %s\n", root->name()); 

위와 같이 하면 std::string으로부터 XML을 파싱할 수 있습니다.
여기서 빨간색 부분을 보시면 const char*를 char*로 변환하는데요, 해보시면 별 문제 없이 잘되는 것 같아 보입니다.
하지만 parse()가 문자열을 변경하지 않는다는 보장이 없습니다.만약 변경해버린다면 예상치 못한 문제가 발생할 것이고, 정말 찾기 힘든 버그가 될 것입니다. 별 문제가 없더라도 아래와 같이 문자열을 복사해서 사용하는 방법을 권장해드립니다.
string strXml = "<?xml version="1.0" encoding="utf-8"?><books>  ... (중략) ...  </books>";

char* sz = new char[strXml.size() + 1];
strcpy(sz, strXml.c_str());

xml_document<> doc;
doc.parse<0>(sz);
delete [] sz;

xml_node<>* root =  doc.first_node();
printf("root 노드 이름: %s\n", root->name());

네 위와 같이 하면... 안됩니다!
원인은 빨간색으로 표시해두었습니다.
parse()는 내부적으로 dom 객체를 만들면서 문자열을 복사하지 않습니다.
기존의 문자열을 그대로 참조합니다.
그래서 parse() 후에 parse()에 사용한 문자열의 데이터를 해제해버리면, 제대로 동작하지 않습니다.

결과적으로 문자열을 파싱하는 방법은 아래와 같습니다.
string strXml = "<?xml version="1.0" encoding="utf-8"?><books>  ... (중략) ...  </books>";
char* sz = new char[strXml.size() + 1];
strcpy(sz, strXml.c_str());

xml_document<> doc;
doc.parse<0>(sz);
xml_node<>* root =  doc.first_node();

printf("root 노드 이름: %s\n", root->name());
delete [] sz;


참고 자료
  [1]  Jordan Schaenzle, "RapidXml – A Lightweight xml Library for C++", http://spin.atomicobject.com/2012/05/20/rapidxml-a-lightweight-xml-library-for-c/, 2015-05-04 확인
  [2] mathematician1975의 답변, "RapidXML compilation error parsing string", http://stackoverflow.com/questions/11604818/rapidxml-compilation-error-parsing-string, 2015-05-04 확인

댓글

이 블로그의 인기 게시물

프로세스 강제 종료 불가 시.

특정 프로세스를 강제 종료 하려는데... "실행 중인 작업 인스턴스가 없습니다." 이런 메시지가 나타나면서 종료가 안되는 문제가 있었습니다. 작업 관리자에서 "프로세스 종료", "프로세스 트리 종료" 해봐도 안되고, cmd에서 taskkill 해봐도 안되고... 그런데 이게 부모 프로세스를 종료하면 자동으로 종료가 되네요.. (제 경우에는 Visual Studio가 부모 프로세스였습니다. ㅋ) 참고: DEVPIA http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=917792&ref=917791