使用Boost读取和写入XML文件有什么好方法(也是一种简单的方法)吗?
我似乎无法使用Boost找到任何简单的示例来读取XML文件。您能指出一个使用Boost读取和编写XML文件的简单示例吗?
如果不是Boost,是否有任何好的和简单的库可以读取和编写您可以推荐的XML文件? (它必须是C ++库)
答案 0 :(得分:63)
你应该尝试pugixml 轻量级,简单快速的C ++ XML解析器
关于pugixml的最好的事情是 XPath 支持,TinyXML和RapidXML缺乏。
引用RapidXML的作者“我要感谢Arseny Kapoulkine在pugixml上的工作,这是该项目的灵感”并且比pugixml快5%-3%,这是我所知道的最快的XML解析器“他已经测试过针对pugixml的0.3版,已达到最近版本0.42。
以下是pugixml文档的摘录:
主要特点是:
好的,你可能会问 - 捕获的是什么?一切都很可爱 - 它是解析XML的小巧,快速,强大,干净的解决方案。缺什么?好的,我们是公平的开发人员 - 所以这是一个错误的列表:
答案 1 :(得分:23)
TinyXML可能是个不错的选择。至于Boost:
Property_Tree中有Boost Repository个库。它已被接受,但目前似乎缺乏支持(编辑:Property_Tree现在是Boost since version 1.41的一部分,关于其XML功能阅读the documentation。)
Daniel Nuffer为Boost Spirit实施了xml parser。
答案 2 :(得分:16)
答案 3 :(得分:10)
提升使用RapidXML中描述的chapter XML Parser of page How to Populate a Property Tree:
不幸的是,截至撰写本文时,XML中没有Boost解析器。 因此,该库包含快速且小巧的RapidXML解析器(目前在 版本1.13)提供XML解析支持。 RapidXML并不完全支持 XML标准;它无法解析DTD,因此无法解析 完全实体替代。
另请参阅XML boost tutorial。
由于OP需要"使用boost来读取和写入xml文件的简单方法" ,我在下面提供了一个非常基本的例子:
<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>
(猫名来自Matt Mahoney's homepage)
C ++中的相应结构:
struct Catowner
{
std::string owner;
std::set<std::string> cats;
};
read_xml()
用法:
#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;
}
write_xml()
用法:
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);
}
答案 4 :(得分:4)
在XML解析的提升中没有特定的库,但是有很多替代方案,这里有几个: libxml, Xerces, Expat
当然,您可以使用boost中的其他一些库来帮助您创建自己的库,但这可能是一项艰巨的任务。
这是IBM关于这个问题的a whole article。
答案 5 :(得分:4)
Boost不提供XML解析器atm。
Poco XML(Poco C++ libs的一部分)非常简单。
答案 6 :(得分:4)
似乎boost序列化可以读取和写入XML中的存档,如果这足以满足您的需要。
答案 7 :(得分:3)
明确使用TinyXML *竖起大拇指*
答案 8 :(得分:2)
查看Arabica
答案 9 :(得分:2)
如果您只是在寻找DOM功能,那么此主题中已有一些建议。我个人可能不会打扰缺乏XPath支持的库,而在C ++中,会使用Qt。还有TinyXPath,阿拉比卡声称有XPath支持,但我不能对这些做任何事情。
答案 10 :(得分:1)
根据我在Boost邮件列表中潜伏的经验,似乎每当XML出现作为主题时,它都会被转移到关于Unicode的讨论中。但是,由于现在有一个潜在的Unicode库迫在眉睫,我认为XML库不会花太长时间出现在那里。
与此同时,我也一直在使用TinyXML。
有关RapidXML的有趣链接。我会看一下。
答案 11 :(得分:1)
警告。我喜欢RapidXML,但在解析UTF16时它有一个非常讨厌的错误。一些有效值会导致崩溃。
我很乐意推荐pugixml - 但它缺少命名空间支持,我知道这会给我带来麻烦。
答案 12 :(得分:1)
有一项GSoC提议工作要改进现有的Boost.XML提案:https://github.com/stefanseefeld/boost.xml但是Andrzej建议Boost.PropertyTree很适合这项任务。具体取决于xml大小和所需的验证支持。
最近在Boost邮件列表中提出了一个图书馆: http://www.codesynthesis.com/projects/libstudxml/doc/intro.xhtml
答案 13 :(得分:0)
boost.spirit怎么样?
Here,他们会显示“迷你XML ”解析器
答案 14 :(得分:0)
<?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;
}