C++ 使用Boost读写XML文件

C++ 使用Boost读写XML文件,c++,xml,boost,C++,Xml,Boost,使用Boost读写XML文件有什么好方法(也是一种简单的方法)吗 我似乎找不到任何使用Boost读取XML文件的简单示例。你能给我举一个使用Boost读写XML文件的简单示例吗 如果不是Boost,有什么好的、简单的库可以用来读写XML文件吗?(必须是C++库)在Boost中没有专门的XML解析库,但是有很多替代方案,这里有一对: , , 当然,您可以使用boost中的一些其他库来帮助您创建自己的库,但这可能是一项艰巨的任务 这里是IBM的主题。还有一个不错的小型C++库。如果您正在寻找一个较

使用Boost读写XML文件有什么好方法(也是一种简单的方法)吗

我似乎找不到任何使用Boost读取XML文件的简单示例。你能给我举一个使用Boost读写XML文件的简单示例吗


如果不是Boost,有什么好的、简单的库可以用来读写XML文件吗?(必须是C++库)

在Boost中没有专门的XML解析库,但是有很多替代方案,这里有一对: , ,

当然,您可以使用boost中的一些其他库来帮助您创建自己的库,但这可能是一项艰巨的任务


这里是IBM的主题。

还有一个不错的小型C++库。如果您正在寻找一个较低级别的库,这是一个很好的起点。

一定要使用TinyXML*竖起大拇指*

根据我在Boost邮件列表中的经验,似乎每次XML作为主题出现时,它都会被转移到关于Unicode的讨论中。然而,由于现在有一个潜在的Unicode库,我认为XML库出现在那里不会花费太长时间

与此同时,我也一直在使用TinyXML


关于RapidXML的有趣链接。我来看看。Boost没有提供XML解析器

Poco XML(的一部分)既好又简单。

可能是一个不错的选择。至于Boost:

图书馆在教室里。它已经被接受,但目前似乎缺乏支持(编辑:现在是Boost的一部分,阅读关于其XML功能的文章)


Daniel Nuffer已经为Boost Spirit实现了一个功能。

请看一看

如果您只寻找DOM功能,本线程中已经有一些建议。我个人可能不会担心缺少XPath支持的库,而C++中会使用Qt。还有TinyXPath,Arabica声称有XPath支持,但我不能对此说任何话。

您应该尝试使用重量轻、简单且快速的XML解析器来实现C++

pugixml最好的地方是XPath支持,而TinyXML和RapidXML则缺乏这种支持

引用RapidXML的作者“我要感谢Arseny Kapoulkine在pugixml上的工作,这是本项目的灵感所在”和“比pugixml快5%-30%,pugixml是我所知道的最快的XML解析器”,他对pugixml的0.3版进行了测试,该版本最近达到了0.42版

以下是pugixml文档的摘录:

其主要特点是:

  • 低内存消耗和碎片化(与pugxml的竞争优势是~1.3倍,与TinyXML的竞争优势是~2.5倍,与Xerces(DOM)的竞争优势是~4.3倍)。通过与现有解析器部分的比较,可以看到确切的数字
  • 极高的解析速度(与pugxml的竞争优势是~6倍,与TinyXML的竞争优势是~10倍,与Xerces DOM的竞争优势是~17.6倍)
  • 极高的解析速度(好吧,我重复我自己的话,但它太快了,在测试XML上比Expat好2.8倍)2
  • 或多或少符合标准(它将正确解析任何符合标准的文件,DTD相关问题除外)
  • 几乎不存在错误(它不会像expat那样被You&Me这样的东西阻塞;它会用错误的编码解析文件;等等)
  • 干净的接口(一个经过大量重构的pugxml接口)
  • 或多或少地了解Unicode(实际上,它假定输入数据采用UTF-8编码,尽管它现在可以很容易地使用ANSI-没有UTF-16(请参阅将来的工作),还可以使用辅助转换函数(UTF-8 UTF-16/32(std::wstring&wchar_t的默认值是什么))
  • 完全标准兼容C++代码(由COMUO严格模式批准);库是多平台(参见平台列表的参考)
  • 高度灵活性。您可以通过解析选项控制文件解析和DOM树构建的许多方面
好的,你可能会问-有什么吸引人的地方吗?一切都很可爱-这是一个小型、快速、健壮、干净的XML解析解决方案。缺少什么?好的,我们是公平的开发人员-下面是一个错误列表:

  • 内存消耗。它打败了我所知道的每一个基于DOM的解析器——但当SAX解析器出现时,就没有机会了。你不能用少于4 Gb的内存处理2 Gb的XML文件——而且速度也不快。虽然pugixml的性能比所有其他基于DOM的解析器都好,所以如果你坚持使用DOM,这不是问题
  • 内存消耗。好的,我再说一遍。当其他解析器允许您在常量存储(甚至作为内存映射区域)中提供XML文件时,pugixml不会。因此您必须将整个数据复制到非常量存储中。此外,它应该在解析器的生存期内保持不变(原因和更多关于生命周期的内容写在下面)。同样,如果您对DOM没有意见,这应该不是问题,因为总体内存消耗更少(好吧,尽管您需要一块连续的内存,这可能是个问题)
  • 缺少验证、DTD处理、XML名称空间、编码的正确处理。如果需要,可以使用MSXML或XercesC或类似的工具

如果满足您的需要,boost序列化似乎可以读取和写入XML格式的归档文件


警告。我喜欢RapidXML,但它在解析UTF16时有一个非常严重的错误。一些有效值会导致它崩溃


我很想推荐pugixml,但它缺乏名称空间支持,我知道这会给我带来问题。

boost.spirit呢?
,它们显示了一个“迷你XML”解析器

GSoC提出了一项改进现有Boost.XML方案的工作:但正如Andrzej提出的那样,Boost.PropertyTree很适合此任务。这取决于XML大小和所需的验证支持

还有一个图书馆是r
<main>
    <owner>Matt</owner>
    <cats>
        <cat>Scarface Max</cat>
        <cat>Moose</cat>
        <cat>Snowball</cat>
        <cat>Powerball</cat>
        <cat>Miss Pudge</cat>
        <cat>Needlenose</cat>
        <cat>Sweety Pie</cat>
        <cat>Peacey</cat>
        <cat>Funnyface</cat>
    </cats>
</main>
struct Catowner
{
    std::string           owner;
    std::set<std::string> cats;
};
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

Catowner load(const std::string &file)
{
    boost::property_tree::ptree pt;
    read_xml(file, pt);

    Catowner co;

    co.owner = pt.get<std::string>("main.owner");

    BOOST_FOREACH(
       boost::property_tree::ptree::value_type &v,
       pt.get_child("main.cats"))
       co.cats.insert(v.second.data());

    return co;
}
void save(const Catowner &co, const std::string &file)
{
   boost::property_tree::ptree pt;

   pt.put("main.owner", co.owner);

   BOOST_FOREACH(
      const std::string &name, co.cats)
      pt.add("main.cats.cat", name);

   write_xml(file, pt);
}
<?xml version="1.0"?>
<Settings>
  <GroupA>
      <One>4</One>
      <Two>7</Two>
      <Three>9</Three> 
  </GroupA>
  <GroupA>
      <One>454</One>
      <Two>47</Two>
      <Three>29</Three> 
  </GroupA>
  <GroupB>
      <A>String A</A>
      <B>String B</B>  
  </GroupB>  
</Settings>
#include <string> 
#include <boost/property_tree/xml_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/foreach.hpp>

bool CMyClass::ReadXML(std::wstring &full_path)
{
    using boost::property_tree::wptree;

    // Populate tree structure pt:
    wptree pt;
    std::wstringstream ss; ss << load_text_file(full_path); // See below for ref.
    read_xml(ss, pt);

    // Traverse pt:
    BOOST_FOREACH(wptree::value_type const& v, pt.get_child(L"Settings"))
    {
        if (v.first == L"GroupA")
        {
            unsigned int n1 = v.second.get<unsigned int>(L"One");
            unsigned int n2 = v.second.get<unsigned int>(L"Two");
            unsigned int n3= v.second.get<unsigned int>(L"Three");
        }
        else if (v.first == L"GroupB")
        {
            std::wstring wstrA = v.second.get<std::wstring>(L"A");
            std::wstring wstrB = v.second.get<std::wstring>(L"B");
        }
    };
}
std::wstring load_text_file(std::wstring &full_path)
{
    std::wifstream wif(full_path);

    wif.seekg(0, std::ios::end);
    buffer.resize(wif.tellg());
    wif.seekg(0);
    wif.read(buffer.data(), buffer.size());

    return buffer;
}