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

时间:2008-11-19 21:07:59

标签: c++ xml serialization

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

平台:linux

你们用什么来生成NOT解析xml?

到目前为止,我正在寻找Foredecker自己生成它的路线 - 这不是一个大文件,但我真的不应该找到一个像样的库来正确生成它。

至于boost,我希望能够做的事情是设置节点名称,在我的节点中设置属性,并摆脱随之而来的所有额外垃圾,因为我并不关心不得不把我的文件放回那个班级。

6 个答案:

答案 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。它还会在一个命令中将其保存到文件中,但我无法找到如何将其保存到缓冲区。