在c ++中生成xml的最简单方法是什么?

我已经使用boost序列化,但是这似乎不允许我生成符合特定模式的xml – 看来它的目的只是保持一个类的状态。

平台:linux

你们用什么来生成不parsingxml?

到目前为止,我正在顺着Foredecker自己生成的路线 – 这不是一个大的文档,但我真的不应该有这么多的麻烦find一个体面的库来正确地生成它。

至于提升,我希望能够做的事情是设置节点名称,在我的节点中设置属性,并摆脱所有附带的废话,因为我真的不在乎必须把我的文件回到那个class。

有些人可能会声明我是一个XML异端 – 但一个有效的方法是用你最喜欢的string输出工具(打印,输出stream等)生成它 – 这可以到一个缓冲区或文件。

一旦保存 – 在提交它之前,您确实应该使用模式进行validation。

对于我们的一个项目,我们有一套非常简单的模板来pipe理开始/结束标签和属性。 这些每个都有一个stream输出操作符。 这使得生成源XML和debugging非常容易。 这使得XML生成代码的结构看起来非常像XML本身。

这样做的一个好处是,如果stream式传输到文件,您可以高效地生成大量的XML。 您将在稍后支付validation费用(假定在昂贵的操作时间更好的时间)。

这种技术的缺点是它只是输出。 它不适合于dynamic创build然后使用XML。

我最近回顾了一堆专门用于生成XML代码的XML库。

执行摘要:我select了TinyXML ++ 。

TinyXML ++具有体面的C ++语法,build立在成熟的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结合的时候),但是重量级并且强制内存pipe理到用户。

RapidXML :非常适合parsing(这是一个现场parsing器, 速度很快 ),但是不适合生成,因为向DOM添加节点需要内存pipe理。

Boost.XML (提案):看起来非常强大,优秀的C ++语法。 然而,它还没有经过审查过程,不受支持,界面可能会改变。 无论如何几乎使用它。 期待它被接受进入Boost。

Libxml ( ++ ):非常好; 强大的,体面的语法。 但是,如果你所做的只是生成 XML,并且绑定到glibmm库(对于ustring),那么这很大。 如果我们在Linux上(像你一样),我会认真考虑的。

XiMOL :独特的基于stream的库。 这对我们的需求来说太简单了,但对于基本的XML生成,您可能会发现它非常有用。 stream语法非常整齐。

希望有一些使用中的东西!

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> 

有一点特别好,就是点分离的path,可以让你隐式创build所有的节点。 文档是相当微薄的,但与ptree.hpp一起应该让你知道它是如何工作的。

哪个平台? MSXML是Windows上的一个选项。 CMarkup是另一个不错的select。 如果.NET是一个选项,它具有优秀的XML支持。

我实际上并没有尝试使用序列化来实现这一点,但据我所知,如果你非常仔细地select你的选项,你可以在模式中设置很多不同的选项(例如防止指针flyweighting和设置某些types的元素名称)

我使用tinyXml ++,它可以很容易地创build如上所述的XML。 它也将它保存到一个命令的文件,但我不知道如何将其保存到缓冲区。