You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 06:40:23