c++ ptree - 使用Boost读写XML文件




8 Answers

您应该尝试使用pugixml 轻量级,简单快速的XML解析器来实现C ++

关于pugixml最好的事情是XPath支持,TinyXML和RapidXML缺乏。

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

以下是pugixml文档的摘录:

主要特点是:

  • 低内存消耗和碎片化(胜过pugxml约为1.3倍,TinyXML - 约2.5倍,Xerces(DOM) - 约4.3倍1)。 在与现有解析器部分的比较中可以看到确切的数字。
  • 极高的解析速度(胜过pugxml约6倍,TinyXML - 约10倍,Xerces-DOM - 约17.6倍1
  • 非常高的解析速度(好吧,我正在重复自己,但速度非常快,在测试XML上它比Expat高出2.8倍)2
  • 或多或少符合标准(它将正确解析任何符合标准的文件,但DTD相关问题除外)
  • 几乎没有错误(它不会像You&Me那样窒息,就像expat一样;它会用错误编码的数据解析文件;等等)
  • 干净的界面(一个重构的pugxml的一个)
  • 或多或少地识别Unicode(实际上,它假设输入数据的UTF-8编码,尽管它很容易使用ANSI - 现在没有UTF-16(参见未来的工作),带有辅助转换函数(UTF-8 < - > UTF-16/32(无论std :: wstring和wchar_t的默认值是什么))
  • 完全符合标准的C ++代码(由Comeau严格模式批准); 该库是多平台的(参见平台列表参考)
  • 灵活性高。 您可以通过解析选项控制文件解析和DOM树构建的许多方面。

好的,你可能会问 - 什么是捕获? 一切都很可爱 - 它是解析XML的小巧,快速,强大,干净的解决方案。 什么不见​​了? 好的,我们是公平的开发人员 - 所以这是一个错误列表:

  • 记忆消耗。 它击败了我所知道的每个基于DOM的解析器 - 但是当SAX解析器出现时,没有机会。 您无法处理内存小于4 Gb的2 Gb XML文件 - 并且可以快速完成。 虽然pugixml比所有其他基于DOM的解析器表现更好,但如果你坚持使用DOM,那就不是问题。
  • 记忆消耗。 好的,我在重复自己。 再次。 当其他解析器允许您在常量存储(或甚至作为内存映射区域)中提供XML文件时,pugixml将不会。 因此,您必须将整个数据复制到非常量存储中。 此外,它应该在解析器的生命周期中持续存在(其原因和更多关于生命期的内容写在下面)。 再说一遍,如果你对DOM没问题 - 这应该不是问题,因为整体内存消耗较少(好吧,虽然你需要一块连续的内存,这可能是一个问题)。
  • 缺乏验证,DTD处理,XML命名空间,正确处理编码。 如果你需要那些 - 请使用MSXML或XercesC或类似的东西。
boost::property_tree::ptree

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

我似乎无法找到使用Boost读取XML文件的任何简单示例。 你能指出一个使用Boost读取和编写XML文件的简单示例吗?

如果不是Boost,是否有任何好的和简单的库来读写您可以推荐的XML文件? (它必须是C ++库)




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




那么在XML解析的提升中没有特定的库,但是有很多替代方案,这里有一对: libxmlXercesExpat

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

以下是IBM关于这一主题的整篇文章







看看Arabica




根据我在Boost邮件列表中潜伏的经验,似乎每当XML出现作为主题时,它都会转向关于Unicode的讨论。 但是,由于现在有一个潜在的Unicode库迫在眉睫,我不认为XML库会在那里出现需要太长时间。

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

关于RapidXML的有趣链接。 我来看看。







<?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>

有一种使用BOOST读取XML的简单方法。 这个例子是基于std :: wstring的:

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



Related

c++ xml boost

Tags

c++   xml   boost