C++ 解析 xml

C++ 解析 xml

C++解析xml可以选择的库比较多,选择最简单的几个进行介绍。
准备工作

<?xml version="1.0" encoding="UTF-8"?>
<Person id="1">
    <name>zsh</name>
    <age>18</age>
    <sex>猛男</sex>
    <weight>120.0</weight>
</Person>

pugixml

pugixml
安装

$ pacman -S mingw-w64-ucrt-x86_64-pugixml

cmake

cmake_minimum_required(VERSION 3.10.0)
project(xml_learn01 VERSION 0.1.0 LANGUAGES C CXX)

# ✅ 设置 C++ 标准
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)  # 强制使用指定标准
set(CMAKE_CXX_EXTENSIONS OFF)        # 禁用编译器扩展(使用纯标准)

# 查找源文件
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
    "src/*.cpp"
    "src/*.c"
)

add_executable(xml_learn01 main.cpp ${SOURCES})

target_include_directories(${CMAKE_PROJECT_NAME}
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/learn01
)

find_package(pugixml CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE pugixml)

include(CTest)
enable_testing()

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

头文件

#ifndef LEARN001_HPP
#define LEARN001_HPP

#include <iostream>
#include <string>
#include <format>

#include <pugixml.hpp>

namespace learn01 {
    void hello();
    void parseXmlToPerson();
}

#endif // LEARN001_HPP

源文件

#include "learn001.hpp"

struct Person{
    std::string name;
    int32_t age;
    std::string sex;
    double weight;
    Person() : name(""), age(0), sex("男"), weight(0.0){
        std::cout << "Person Construct1...\n";
    }
    Person(const std::string name, const int age, const std::string sex, const double weight) : name(name), age(age), sex(sex), weight(weight){
        std::cout << "Person Construct2...\n";
    }
    ~Person(){
        std::cout << "Person Deconstruct...\n";
    }
    friend std::ostream& operator<<(std::ostream& os, const Person& person){
        os << std::format("Person(name={}, age={}, sex={}, weight={})", person.name, person.age, person.sex, person.weight);
        return os;
    }
};

namespace learn01 {
    void hello(){
        std::cout << "Hello World\n";
    }
    void parseXmlToPerson(){
        pugi::xml_document document;
        const pugi::xml_parse_result result = document.load_file("../hello.xml");
        if(result.status != pugi::status_ok){
            std::cerr << result.description() << "\n";
            return;
        }
        pugi::xml_node personNode = document.child("Person");
        const auto id = personNode.attribute("id").value();
        std::cout << "id: " << id << "\n";
        const auto name = personNode.child_value("name");
        const auto age = personNode.child_value("age");
        const auto sex = personNode.child_value("sex");
        const auto weight = personNode.child_value("weight");
        Person p(name, std::stoi(age), sex, std::stod(weight));
        std::cout << p << "\n";
    }
}

RapidXML

RapidXML
点击download下载即可,然后引入头文件即可。

cmake_minimum_required(VERSION 3.10.0)
project(xml_learn01 VERSION 0.1.0 LANGUAGES C CXX)

# ✅ 设置 C++ 标准
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)  # 强制使用指定标准
set(CMAKE_CXX_EXTENSIONS OFF)        # 禁用编译器扩展(使用纯标准)

# 查找源文件
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
    "src/*.cpp"
    "src/*.c"
)

add_executable(xml_learn01 main.cpp ${SOURCES})

target_include_directories(${CMAKE_PROJECT_NAME}
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/learn01
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/rapidxml
)

find_package(pugixml CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE pugixml)

include(CTest)
enable_testing()

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

头文件

#ifndef LEARN001_HPP
#define LEARN001_HPP

#include <iostream>
#include <string>
#include <format>
#include <vector>
#include <fstream>
#include <iterator> 

#include <pugixml.hpp>
#include <rapidxml.hpp>

namespace learn01 {
    void hello();
    void parseXmlToPerson();
    void parseXmlToPerson1();
}

#endif // LEARN001_HPP

源文件

#include "learn001.hpp"

struct Person{
    std::string name;
    int32_t age;
    std::string sex;
    double weight;
    Person() : name(""), age(0), sex("男"), weight(0.0){
        std::cout << "Person Construct1...\n";
    }
    Person(const std::string name, const int age, const std::string sex, const double weight) : name(name), age(age), sex(sex), weight(weight){
        std::cout << "Person Construct2...\n";
    }
    ~Person(){
        std::cout << "Person Deconstruct...\n";
    }
    friend std::ostream& operator<<(std::ostream& os, const Person& person){
        os << std::format("Person(name={}, age={}, sex={}, weight={})", person.name, person.age, person.sex, person.weight);
        return os;
    }
};

namespace learn01 {
    void hello(){
        std::cout << "Hello World\n";
    }
    void parseXmlToPerson(){
        pugi::xml_document document;
        const pugi::xml_parse_result result = document.load_file("../hello.xml");
        if(result.status != pugi::status_ok){
            std::cerr << result.description() << "\n";
            return;
        }
        pugi::xml_node personNode = document.child("Person");
        const auto id = personNode.attribute("id").value();
        std::cout << "id: " << id << "\n";
        const auto name = personNode.child_value("name");
        const auto age = personNode.child_value("age");
        const auto sex = personNode.child_value("sex");
        const auto weight = personNode.child_value("weight");
        Person p(name, std::stoi(age), sex, std::stod(weight));
        std::cout << p << "\n";

    }
    void parseXmlToPerson1(){
        std::ifstream xmlFile("../hello.xml");
        if(!xmlFile.is_open()){
            std::cerr << "文件打开失败\n";
            return;
        }
        std::string line;
        while(std::getline(xmlFile, line)){
            std::cout << line << "\n";
        }
        std::cout << "=========================\n";
        xmlFile.clear();
        xmlFile.seekg(std::streampos(0LL));
        std::string xmlContent{
            std::istreambuf_iterator<char>(xmlFile),
            std::istreambuf_iterator<char>()
        };
        std::cout << xmlContent << "\n";
        // 开始解析
        rapidxml::xml_document<> doc;
        // doc.parse<0>(&xmlContent[0]); // 取首char数组元素指针
        doc.parse<0>(xmlContent.data()); // C++ 17
        const auto personNode = doc.first_node();
        const auto nameNode = personNode->first_node("name");
        const auto ageNode = personNode->first_node("age");
        const auto sexNode = personNode->first_node("sex");
        const auto weightNode = personNode->first_node("weight");
        std::cout << std::format(
            "根节点name: {} -> value: {}, 子节点name: {} -> value: {}, "
            "子节点name: {} -> value: {}, 子节点name: {} -> value: {}, "
            "子节点name: {} -> value: {}",
            personNode->name(), personNode->value(), nameNode->name(),
            nameNode->value(), ageNode->name(), ageNode->value(),
            sexNode->name(), sexNode->value(), weightNode->name(),
            weightNode->value());
        Person p(nameNode->value(), std::stoi(ageNode->value()), sexNode->value(), std::stod(weightNode->value()));
        std::cout << p << "\n";
        xmlFile.close();
    }
}

tinyxml2

pacman -S mingw-w64-ucrt-x86_64-tinyxml2

cmake

cmake_minimum_required(VERSION 3.10.0)
project(xml_learn01 VERSION 0.1.0 LANGUAGES C CXX)

# ✅ 设置 C++ 标准
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)  # 强制使用指定标准
set(CMAKE_CXX_EXTENSIONS OFF)        # 禁用编译器扩展(使用纯标准)

# 查找源文件
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
    "src/*.cpp"
    "src/*.c"
)

add_executable(xml_learn01 main.cpp ${SOURCES})

target_include_directories(${CMAKE_PROJECT_NAME}
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/learn01
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/rapidxml
)

find_package(pugixml CONFIG REQUIRED)
find_package(tinyxml2 CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE pugixml)
target_link_libraries(${PROJECT_NAME} PRIVATE tinyxml2::tinyxml2)

include(CTest)
enable_testing()

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

头文件
Person对象非常简单,我就懒得拆分了。

#ifndef LEARN001_HPP
#define LEARN001_HPP

#include <iostream>
#include <string>
#include <format>
#include <vector>
#include <fstream>
#include <iterator> 

#include <pugixml.hpp>
#include <rapidxml.hpp>
#include <tinyxml2.h> // 内部兼容 C++

namespace learn01 {
    void hello();
    void parseXmlToPerson();
    void parseXmlToPerson1();
    void parseXmlToPerson2();
}

#endif // LEARN001_HPP

源文件

#include "learn001.hpp"

struct Person{
    std::string name;
    int32_t age;
    std::string sex;
    double weight;
    Person() : name(""), age(0), sex("男"), weight(0.0){
        std::cout << "Person Construct1...\n";
    }
    Person(const std::string name, const int age, const std::string sex, const double weight) : name(name), age(age), sex(sex), weight(weight){
        std::cout << "Person Construct2...\n";
    }
    ~Person(){
        std::cout << "Person Deconstruct...\n";
    }
    void setName(const std::string name){
        this->name = name;
    }
    void setAge(const int age){
        this->age = age;
    }
     void setSex(const std::string sex){
        this->sex = sex;
    }
     void setWeight(const double weight){
        this->weight = weight;
    }
    friend std::ostream& operator<<(std::ostream& os, const Person& person){
        os << std::format("Person(name={}, age={}, sex={}, weight={})", person.name, person.age, person.sex, person.weight);
        return os;
    }
};

namespace learn01 {
    void hello(){
        std::cout << "Hello World\n";
    }
    void parseXmlToPerson(){
        pugi::xml_document document;
        const pugi::xml_parse_result result = document.load_file("../hello.xml");
        if(result.status != pugi::status_ok){
            std::cerr << result.description() << "\n";
            return;
        }
        pugi::xml_node personNode = document.child("Person");
        const auto id = personNode.attribute("id").value();
        std::cout << "id: " << id << "\n";
        const auto name = personNode.child_value("name");
        const auto age = personNode.child_value("age");
        const auto sex = personNode.child_value("sex");
        const auto weight = personNode.child_value("weight");
        Person p(name, std::stoi(age), sex, std::stod(weight));
        std::cout << p << "\n";

    }
    void parseXmlToPerson1(){
        std::ifstream xmlFile("../hello.xml");
        if(!xmlFile.is_open()){
            std::cerr << "文件打开失败\n";
            return;
        }
        std::string line;
        while(std::getline(xmlFile, line)){
            std::cout << line << "\n";
        }
        std::cout << "=========================\n";
        xmlFile.clear();
        xmlFile.seekg(std::streampos(0LL));
        std::string xmlContent{
            std::istreambuf_iterator<char>(xmlFile),
            std::istreambuf_iterator<char>()
        };
        std::cout << xmlContent << "\n";
        // 开始解析
        rapidxml::xml_document<> doc;
        // doc.parse<0>(&xmlContent[0]); // 取首char数组元素指针
        doc.parse<0>(xmlContent.data()); // C++ 17
        const auto personNode = doc.first_node();
        const auto nameNode = personNode->first_node("name");
        const auto ageNode = personNode->first_node("age");
        const auto sexNode = personNode->first_node("sex");
        const auto weightNode = personNode->first_node("weight");
        std::cout << std::format(
            "根节点name: {} -> value: {}, 子节点name: {} -> value: {}, "
            "子节点name: {} -> value: {}, 子节点name: {} -> value: {}, "
            "子节点name: {} -> value: {}",
            personNode->name(), personNode->value(), nameNode->name(),
            nameNode->value(), ageNode->name(), ageNode->value(),
            sexNode->name(), sexNode->value(), weightNode->name(),
            weightNode->value());
        Person p(nameNode->value(), std::stoi(ageNode->value()), sexNode->value(), std::stod(weightNode->value()));
        std::cout << p << "\n";
        xmlFile.close();
    }
    void parseXmlToPerson2(){
        tinyxml2::XMLDocument doc;
        const auto result = doc.LoadFile("../hello.xml");
        if(result != tinyxml2::XML_SUCCESS){
            std::cout << "加载xml文件失败\n";
            return;
        }
        const auto personNode = doc.FirstChildElement("Person");
        for(auto item = personNode->FirstChildElement("name"); item; item = item->NextSiblingElement()){
            std::cout << item->GetText() << "\n";
        }
        const auto nameNode = personNode->FirstChildElement("name");
        const auto ageNode = nameNode->NextSiblingElement();
        const auto sexNode = ageNode->NextSiblingElement();
        const auto weightNode = sexNode->NextSiblingElement();
        try{
            std::cout << nameNode->GetText() << '\n';
            std::cout << ageNode->GetText() << '\n';
            std::cout << sexNode->GetText() << '\n';
            std::cout << weightNode->GetText() << '\n';
        } catch(const std::exception& e) {
            std::cerr << e.what() << '\n';
        }
        Person p(nameNode->GetText(), std::stoi(ageNode->GetText()), sexNode->GetText(), std::stod(weightNode->GetText()));
        std::cout << p << "\n";
    }
}
posted @ 2025-11-09 16:20  爱情丶眨眼而去  阅读(5)  评论(0)    收藏  举报