我已经使用了boost序列化,但这似乎不允许我生成符合特定模式的xml - 似乎它的目的只是为了保持一个类的状态。
平台:linux
你们用什么来生成NOT解析xml?
到目前为止,我正在寻找Foredecker自己生成它的路线 - 这不是一个大文件,但我真的不应该找到一个像样的库来正确生成它。
至于boost,我希望能够做的事情是设置节点名称,在我的节点中设置属性,并摆脱随之而来的所有额外垃圾,因为我并不关心不得不把我的文件放回那个班级。
答案 0 :(得分:47)
我最近审查了一堆专门用于生成XML代码的XML库。
执行摘要:我选择使用TinyXML++。
TinyXML ++具有不错的C ++语法,建立在成熟的TinyXML C库之上,是免费的&开源(MIT许可证)和小。简而言之,它有助于快速完成工作。这是一个快速摘录:
Document doc;
Node* root(doc.InsertEndChild(Element("RootNode")));
Element measurements("measurements");
Element tbr("TotalBytesReceived", 12);
measurements.InsertEndChild(tbr);
root->InsertEndChild(measurements);
产生:
<RootNode>
<measurements>
<TotalBytesReceived>12</TotalBytesReceived>
</measurements>
</RootNode>
我对它很满意。
我回顾了很多其他人;这里有一些更好的竞争者:
Xerces:国王爸爸。是所有(特别是与Xalan结合使用时)但重量级并强制对用户进行内存管理。
RapidXML:非常适合解析(它是一个原位解析器并且快速)但不适合生成,因为向DOM添加节点需要内存管理。
Boost.XML(提案):看起来很棒 - 功能强大,出色的C ++语法。但是,它尚未完成审核过程,不受支持且界面可能会发生变化。无论如何几乎都用过它。期待它被Boost接受。
Libxml(++):非常好;强大,体面的语法。但是,如果您所做的只是生成 XML并且与glibmm库(用于ustring)相关联,那就太大了。如果我们只在Linux上 (就像你自己一样?)我会认真考虑。
XiMOL:独特的基于流的库。这对我们的需求来说有点过于简单,但对于基本的XML生成,您可能会发现它非常有用。流语法很整洁。
希望有些东西可供使用!
答案 1 :(得分:13)
有些人可能会声明我是一个XML异端 - 但一种有效的方法是使用您喜欢的字符串输出工具(打印,输出流等)生成它 - 这可以转到缓冲区或文件。
保存后 - 您确实应该在提交之前使用架构进行验证,然后将其发送出去。
对于我们的一个项目,我们有一套非常简单的模板,用于管理开始/结束标记和属性。这些都有一个流输出操作符。这使得生成源XML和调试变得非常容易。这使得XML生成代码的结构看起来非常像XML本身。
这样做的一个优点是,如果流式传输到文件,您可以有效地生成大量XML。您将在稍后支付验证费用(大概是在更昂贵的时间进行昂贵的操作)。
这种技术的缺点是它本质上只是输出。它不适合动态创建然后使用XML。
答案 2 :(得分:9)
Boost.PropertyTree 是生成XML的一种不错的直接方式 - 特别是如果您已经在使用Boost。
以下是一个完整的示例程序:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
using boost::property_tree::ptree;
using boost::property_tree::write_xml;
using boost::property_tree::xml_writer_settings;
int wmain(int argc, wchar_t* argv[]) {
char* titles[] = {"And Then There Were None", "Android Games", "The Lord of the Rings"};
ptree tree;
tree.add("library.<xmlattr>.version", "1.0");
for (int i = 0; i < 3; i++) {
ptree& book = tree.add("library.books.book", "");
book.add("title", titles[i]);
book.add("<xmlattr>.id", i);
book.add("pageCount", (i+1) * 234);
}
// Note that starting with Boost 1.56, the template argument must be std::string
// instead of char
write_xml("C:\\Users\\Daniel\\Desktop\\test.xml", tree,
std::locale(),
xml_writer_settings<char>(' ', 4));
return 0;
}
生成的XML如下所示:
<?xml version="1.0" encoding="utf-8"?>
<library version="1.0">
<books>
<book id="0">
<title>And Then There Were None</title>
<pageCount>234</pageCount>
</book>
<book id="1">
<title>Android Games</title>
<pageCount>468</pageCount>
</book>
<book id="2">
<title>The Lord of the Rings</title>
<pageCount>702</pageCount>
</book>
</books>
</library>
特别好的一点是点分隔路径,允许您隐式创建沿途的所有节点。 documentation相当微不足道,但与ptree.hpp
一起应该会让您知道它是如何运作的。
答案 3 :(得分:0)
哪个平台? MSXML是Windows上的一个选项。 CMarkup是另一个不错的选择。 如果.NET是一个选项,它具有出色的XML支持。
答案 4 :(得分:0)
我实际上没有尝试使用boost序列化来执行此操作,但据我了解,如果您非常仔细地选择了您的选项,则可以在架构中设置许多不同的选项(例如防止指针飞行加权和设置元素名称对于某些类型)
答案 5 :(得分:0)
我使用tinyXml ++,它可以很容易地创建上面发布的xml。它还会在一个命令中将其保存到文件中,但我无法找到如何将其保存到缓冲区。