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";
}
}

浙公网安备 33010602011771号