XML 처리 라이브러리 pugixml 소개
pugixml은 경량이며 고성능의 C++ 기반 XML 파서로, 구조화된 데이터를 효율적으로 읽고 쓸 수 있도록 설계되었습니다. 주요 특징은 다음과 같습니다:
- DOM 유사 인터페이스 제공 — 트리 탐색 및 수정에 용이
- 빠른 비검증 파싱 속도 — 대용량 파일 처리에 적합
- XPath 1.0 지원 — 복잡한 노드 접근 가능
- 유니코드 완전 지원 — 인코딩 자동 변환 기능 포함
- 헤더 파일만으로 사용 가능 — 컴파일 의존성 최소화
공식 저장소: https://github.com/zeux/pugixml
XML 형식의 핵심 요소
XML은 구성 정보나 설정 파일 등 다양한 시스템에서 널리 사용되는 구조적 데이터 포맷입니다.
- 계층 구조: 태그 계층을 통해 데이터 관계 표현
- 속성 지원: 태그 내부에 추가 메타데이터 포함 가능
- 주석 기능: 주석은 해석되지 않으며, 문서 설명용으로 활용
기본 사용 방법
헤더 포함 및 초기 설정
#include "pugixml.hpp"
using namespace pugi;
XML 파일 로드 및 데이터 추출
예제 파일 (config.xml) 내용:
<settings>
<host>localhost</host>
<port>8080</port>
<debug>true</debug>
</settings>
파일에서 데이터를 읽는 예제 코드:
int loadConfig() {
xml_document doc;
xml_parse_result result = doc.load_file("config.xml");
if (!result) return -1;
xml_node root = doc.child("settings");
xml_node host = root.child("host");
xml_node port = root.child("port");
xml_node debug = root.child("debug");
std::cout << "Host: " << host.text().as_string() << std::endl;
std::cout << "Port: " << port.text().as_int() << std::endl;
std::cout << "Debug: " << debug.text().as_bool() << std::endl;
return 0;
}
반복자 기반 트리 탐색
하위 노드 목록을 순회할 때 반복자 사용이 효과적입니다:
for (auto child : doc.child("data").children("item")) {
std::string value = child.text().as_string();
std::cout << "Item: " << value << std::endl;
}
XPath를 이용한 정확한 노드 선택
복잡한 조건으로 특정 노드를 찾을 수 있습니다:
int queryWithXPath() {
xml_document doc;
doc.load_file("config.xml");
xpath_node_set results = doc.select_nodes("//settings/port");
for (xpath_node node : results) {
std::cout << "Port Value: " << node.node().text().as_int() << std::endl;
}
return 0;
}
XML 생성 및 파일 저장
새로운 XML 문서를 작성하고 파일로 저장하는 방법:
int generateXML() {
xml_document doc;
// 선언 추가
xml_node decl = doc.prepend_child(node_declaration);
decl.append_attribute("version") = "1.0";
decl.append_attribute("encoding") = "utf-8";
// 주석 추가
xml_node comment = doc.append_child(node_comment);
comment.set_value("Generated by pugixml");
// 루트 노드 생성
xml_node root = doc.append_child("configuration");
xml_node setting = root.append_child("option");
setting.append_attribute("name") = "enable_log";
setting.append_child(node_pcdata).set_value("yes");
// 파일로 저장
doc.save_file("./generated_config.xml");
return 0;
}
프로젝트에 라이브러리 통합하기
CMake 기반 프로젝트에 통합하는 방법:
cmake_minimum_required(VERSION 3.0)
project(xml_processor LANGUAGES CXX)
add_executable(app main.cpp)
# pugixml 라이브러리 정의
include_directories(pugixml/src)
add_library(pugixml STATIC pugixml/src/pugixml.cpp)
target_link_libraries(app pugixml)
빌드 수행
mkdir build && cd build
cmake ..
make
공유 라이브러리로 변경
정적 라이브러리 대신 공유 라이브러리 사용 시:
add_library(pugixml SHARED pugixml/src/pugixml.cpp)
크로스 컴파일 설정
ARM 또는 다른 아키텍처로 빌드할 경우, 컴파일러 지정:
cmake -D CMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ ..