使用libzip与pugixml生成压缩包后XML文件编码异常求助
问题:用pugixml+libzip生成的XML文件开头编码乱码
用pugixml构建XML文档,再通过libzip将其写入ZIP压缩包,代码运行无报错,但解压后打开XML文件发现开头乱码,XML声明部分被破坏。
相关代码
Main.cpp
#include <iostream> #include <sstream> #include <zip.h> #include <pugixml.hpp> #include <memory> using namespace std; int main() { auto document = std::unique_ptr<pugi::xml_document>(new pugi::xml_document); pugi::xml_node declNode = document->prepend_child(pugi::node_declaration); declNode.append_attribute("version") = "1.0"; declNode.append_attribute("encoding") = "UTF-8"; declNode.append_attribute("standalone") = "yes"; pugi::xml_node rootNode = document->append_child("Document"); rootNode.append_child("Files"); int err = 0; zip_t* zip = zip_open("test.zip", ZIP_CREATE, &err); { std::stringstream ss; document->save(ss, " "); std::string buffer = ss.str(); auto src = zip_source_buffer_create(buffer.c_str(), buffer.length(), 0, 0); zip_file_add(zip, "Document.xml", src, ZIP_FL_ENC_UTF_8); } zip_close(zip); return 0; }
异常现象
解压后Document.xml内容:
~U Ä U rsion="1.0" encoding="UTF-8" standalone="yes"?> <Document> <Files /> </Document>
十六进制开头字节显示异常,无法正确解析为<?xml标识。
问题原因
使用std::stringstream保存XML时,系统全局locale可能干扰字符编码转换,导致pugixml输出的UTF-8字节被错误转码;同时std::stringstream的默认处理逻辑无法精准保留UTF-8原始字节。
解决方案
改用pugixml自带的xml_writer_buffer直接获取XML的UTF-8字节数据,彻底避免locale的影响:
修改后完整代码
#include <iostream> #include <zip.h> #include <pugixml.hpp> #include <memory> using namespace std; int main() { auto document = std::unique_ptr<pugi::xml_document>(new pugi::xml_document); pugi::xml_node declNode = document->prepend_child(pugi::node_declaration); declNode.append_attribute("version") = "1.0"; declNode.append_attribute("encoding") = "UTF-8"; declNode.append_attribute("standalone") = "yes"; pugi::xml_node rootNode = document->append_child("Document"); rootNode.append_child("Files"); int err = 0; zip_t* zip = zip_open("test.zip", ZIP_CREATE, &err); { pugi::xml_writer_buffer writer_buffer; // 显式指定UTF-8编码输出,避免歧义 document->save(writer_buffer, " ", pugi::format_default, pugi::encoding_utf8); std::string buffer(writer_buffer.data(), writer_buffer.size()); auto src = zip_source_buffer_create(buffer.c_str(), buffer.size(), 0, nullptr); if (src) { zip_file_add(zip, "Document.xml", src, ZIP_FL_ENC_UTF_8); } else { cerr << "创建zip数据源失败" << endl; } } zip_close(zip); return 0; }
补充说明
xml_writer_buffer是pugixml原生提供的字节缓冲区写入工具,不受系统locale影响,能精准保留UTF-8编码的原始字节。- 调用
save时显式指定pugi::encoding_utf8,确保输出编码与XML声明的编码一致。 - 新增了
src空指针检查,避免空指针调用带来的潜在崩溃问题。
内容的提问来源于stack exchange,提问作者Al Tilmidh
相关产品推荐
相关产品推荐

