2008-11-19 120 views
14

我已经使用了boost序列化,但是这似乎并不允许我生成符合特定模式的xml - 它似乎只是为了坚持一个类的状态。在C++中生成xml最简单的方法是什么?

平台:Linux

你们有什么用,产生无法解析的XML?

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

至于提升,我希望能够做的事情是设置节点名称,在我的节点中设置属性,并摆脱它附带的所有额外的垃圾,因为我真的不在乎关于必须将我的文档重新放入该类。

+0

我已经使用[libxml ++](http://libxmlplusplus.sourceforge.net/)来生成XML,但我不能保证它是最简单的方法! :-) – 2008-11-19 21:10:53

回答

10

有些人可能会声明我是一个XML异端 - 但一种有效的方法是用您最喜欢的字符串输出工具(打印,输出流等)生成它 - 这可以进入缓冲区或文件。

一旦保存 - 您确实应该在提交它之前验证它的模式。

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

这样做的一个优点是,如果流式传输到文件,则可以高效地生成大量XML。您将在稍后支付验证费用(假定在昂贵的操作时间较好的时候)。

这种技术的不足之处在于它仅仅是输出。它不适合于动态创建然后消耗XML。

+0

非常感谢!我在网上,新闻组,irc等网站上花费了2-3个小时......在过去的20分钟里,我建立了一个发电机,它完全符合我使用这种方法所需要做的 - 这不是很美,需要工作,但它工作 - thnx! – eyberg 2008-11-19 22:28:36

+3

是的,异端! ;)尽管如此,我建议不要走这条路线 - 有许多图书馆可以帮助你避免在你的XML中犯错误。 – MattyT 2008-11-19 23:03:19

+0

那么,我一直在生成我自己的XML多年没有问题。就像Foredecker一样,我们的XML相对比较简单,但也许比他所说的更复杂。 – Rob 2010-10-19 11:21:01

0

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

0

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

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++):Very good;强大的,体面的语法。但是,如果你所做的只是生成 XML并且绑定到glibmm库(对于ustring),那么它很大。如果我们在Linux上只有(就像你自己一样?)我会认真考虑的。

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

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

0

我使用tinyXml ++,它可以很容易地创建xml,如上所述。它也将它保存到一个命令的文件,但我无法找到如何将其保存到缓冲区。

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一起应该给你一个它的工作原理。

相关问题