pugixml을 활용한 XML 데이터 처리 기법

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++ ..

태그: pugixml XML Parsing C++ cmake XPath

6월 30일 04:03에 게시됨