【问题标题】:what's the easiest way to generate xml in c++?在 C++ 中生成 xml 的最简单方法是什么?
【发布时间】:2010-09-23 03:13:20
【问题描述】:

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

平台:linux

你们用什么来生成 NOT parse xml?

到目前为止,我正在走 Foredecker 自己生成它的路线——它不是一个大文档,但我真的不应该在找到一个像样的库来正确生成它时遇到这么多麻烦。

至于提升,我想做的事情是设置节点名称,在我的节点中设置属性,并摆脱它带来的所有额外废话,因为我并不真正关心不得不将我的文档放回那个类。

【问题讨论】:

  • 我已经使用libxml++ 来生成XML,但我不能保证这是最简单的方法! :-)

标签: c++ xml serialization


【解决方案1】:

我最近查看了一组专门用于生成 XML 代码的 XML 库。

执行摘要:我选择了TinyXML++

TinyXML++ 有不错的 C++ 语法,建立在成熟的 TinyXML C 库之上,是免费和开源的(MIT 许可证)并且很小。简而言之,它有助于快速完成工作。这是一个快速的 sn-p:

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 生成,您可能会发现它非常有用。流语法相当简洁。

希望里面有一些有用的东西!

【讨论】:

  • 查看 TinyXML++ 问题页面,它似乎有一些内存泄漏。你经历过吗?
  • @mlimber 我经常使用它并且没有,但我只将它用于相对较小的文档
  • 嗯,看看最里面的元素,我怀疑输出和代码是否匹配。 :-)
  • 只是一个小提示:在使用 TinyXML 之后,我发现了 pugiXML。内存对我来说至关重要,我正在解析巨大的 XML 树。与一个 800MB 的 XML 文件进行了快速比较。 TinyXML 需要 9.5GB (!) 的 ram 来解析它,而 pugiXML 需要大约 3.5GB。
【解决方案2】:

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

一旦保存 - 您真的应该在提交之前使用架构进行验证,然后再将其发送出去。

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

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

这种技术的缺点是它本质上只是输出。它不适合动态创建然后使用 XML。

【讨论】:

  • 非常感谢!我在过去的 2-3 个小时里搜索了网络、新闻组、irc 等……在过去的 20 分钟里,我构建了一个生成器,它完全可以使用这种方法完成我需要做的事情——它并不漂亮;需要工作,但它确实有效 - thnx!
  • 是的,异端! ;) 说真的,我建议不要走这条路 - 有很多库可以帮助并防止您在 XML 中犯错误。
  • 好吧,多年来我一直在生成自己的 XML,没有出现任何问题。与 Foredecker 一样,我们的 XML 相对简单,但可能比他所说的更复杂。
  • 我本能地同意这个答案,除了你可能最终需要逃避一些事情。 ”和&对于大多数用途来说可能已经足够了,但是如果您的数据足够多样化,那么无论如何您最终都会编写半个通用 XML 输出生成器......
【解决方案3】:

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 一起应该可以让您了解它的工作原理。

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • CMarkup 也可以在没有 .Net 的情况下工作。您可以构建它以使用 std::string 或 MFC CString。如果这是一个问题,它会在内存中构建整个文档
    【解决方案5】:

    我实际上并没有尝试过提升序列化来做到这一点,但据我了解,如果你非常仔细地选择你的选项,你可以在模式中设置很多不同的选项(例如防止指针飞行权重和设置元素名称对于某些类型)

    【讨论】:

      【解决方案6】:

      我使用 tinyXml++,它可以很容易地创建上面发布的 xml。它还会在一个命令中将其保存到文件中,但我不知道如何将其保存到缓冲区。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多