【问题标题】:What's a good way to write XML in C++?用 C++ 编写 XML 的好方法是什么?
【发布时间】:2010-06-06 23:28:27
【问题描述】:

解析 XML 的库有很多,但用 C++ 编写 XML 的好(?)方法似乎不多。

到目前为止我一直在使用的库:

  • PugiXML:非常轻量级、非常简单的 API,但似乎缺少编写 XML 的方法(或者我还没有找到)
  • RapidXML:我对 RapidXML 没有太多经验;但它确实看起来不错。
  • TinyXML:我觉得奇怪的是 STL TinyXML 需要在 TinyXML 中显式“启用” - 我的意思是,如果您的编译器不支持 STL,那就换一个更好的!

无论如何,为了明确我的观点,我已经编写了一个 PHP 脚本,它可以执行我计划在 C++ 中执行的操作:http://codepad.org/RyhQSgcm

非常感谢任何帮助!

【问题讨论】:

  • 除了你不喜欢你必须设置一个宏来启用对 STL 的支持之外,TinyXML 有什么问题?
  • @James McNellis:上次我尝试使用“C++”“wr​​apper”“ticpp”附带的示例(实际上我觉得这有点讽刺),程序只是出现了段错误。快速分析表明错误来自 TinyXML。所以我停止使用它。
  • @nebukadnezzar:我广泛使用了 TinyXML,从来没有遇到过问题。它并不完美,但它易于使用且速度足以满足大多数用途。
  • @nebukadnezzar:如果你正在寻找一个完美的库,我唯一的建议就是开始编写它!
  • @James:……习惯失望。

标签: c++ xml


【解决方案1】:

Xerces DOM Parser

Xerces-C++ 是用 C++ 的可移植子集编写的验证 XML 解析器。 Xerces-C++ 使您的应用程序能够轻松地读取和写入 XML 数据。提供了一个共享库,用于使用 DOM、SAX 和 SAX2 API 解析、生成、操作和验证 XML 文档。有关使用 Xerces-C++ 进行编程的介绍,请参阅编程指南。

The POCO project 也有一个 XMLWriter 可以让你生成 XML。

当然总是有this existing StackOverflow post

【讨论】:

  • 尽管如果“轻量级”是要求的一部分(这似乎来自 nebukadnezzar 已经尝试过的其他库示例),那么 Xerces 完全是在 that i> 规模!
  • @cedeka:是的,尽管我没有明确添加为需求,但我正在寻找一个轻量级库。
  • @codeka 我认为在我提到的三个选项之间已经涵盖了这一点。
  • @nebukadnezzar 我提到的 stackoverflow 的现有帖子也涵盖了这一点。这真是一个重复的问题。
  • @Romain Hippeau:我不想承认,但 tinyxml++ 似乎是这里最好的解决方案。
【解决方案2】:

我使用 std::ostream::operator() 和一个简单的函数,它会在必要时引用一个字符串。 当您只想将现有数据导出到 XML 中时,花费时间和内存来构建 DOM 似乎需要很长的路要走...

【讨论】:

    【解决方案3】:

    如果您使用 C++ 工作,您应该再次考虑使用 ticpp。使用任何处理流的东西所期望的确切语法来设置和输出(简单)有效 xml 并不需要太多。

    This link 展示了如何使用该库,其中包含的构建说明足以让一切设置完成。

    【讨论】:

      【解决方案4】:

      因为你特别提到了轻量级,我没看到有提过,我加Boost.PropertyTree。它在底层使用 RapidXML。

      它除了解析元素什么都不做,但有时这就足够了。老实说,XML 模式验证、XPath 等。应该被分成不同的库。与提供这种额外覆盖的现有 C++ 合并可能并不难。

      示例 XML 文件/字符串:

      std::string xml_providers =
          "<question>"
          "   <title>What’s a good way to write XML in C++?</title>"
          "   <date>2010/6/6</date>"
          "</question>"
          "<providers>"
          "   <provider speed=\"1\">Boost.PropertyTree</provider>"
          "   <provider speed=\"6\">TinyXML++</provider>"
          "   <provider speed=\"3\">PugiXML</provider>"
          "   <provider speed=\"9001\">Xerxes</provider>"
          "   <provider speed=\"1\">RapidXML</provider>"
          "</providers>";
      

      boost::property_tree 会这样使用:

      using boost::property_tree::xml_parser::read_xml;
      using boost::property_tree::ptree;
      using boost::gregorian::from_string;
      using boost::gregorian::date;
      
      ptree doc;
      std::istringstream iss(xml_providers);
      xml_parser::read_xml(iss, doc);
      
      std::string title = doc.get<std::string>("question.title");
      date when = from_string(doc.get<std::string>("question.date"));
      ptree providers = doc.get_child("providers");
      std::size_t size = std::distance(providers.begin(), providers.end());
      
      std::cout << "Question: " << title << std::endl;
      std::cout << "Asked on: " << when << std::endl;
      std::cout << size << " suggested XML providers" << std::endl << std::endl;
      std::cout << std::left << std::setw(25)
          << "Provider" << "Speed" << std::endl;
      
      providers.sort(sort_by_speed);
      std::for_each(providers.begin(), providers.end(), send_to_cout);
      

      还有两个辅助函数:

      auto sort_by_speed = [](ptree::value_type& a, ptree::value_type& b) -> bool {
          int a_speed = a.second.get<int>("<xmlattr>.speed");
          int b_speed = b.second.get<int>("<xmlattr>.speed");
          return a_speed < b_speed;
      };
      auto send_to_cout = [](ptree::value_type& provider) {
          std::cout << std::left << std::setw(25)
              << provider.second.get_value<std::string>()
              << provider.second.get<int>("<xmlattr>.speed") << std::endl;
      };
      

      输出:

      问题:用 C++ 编写 XML 的好方法是什么? 提问时间:2010 年 6 月 6 日 5 个建议的 XML 提供程序 提供者速度 Boost.PropertyTree 1 快速XML 1 普吉XML 3 TinyXML++ 6 薛西斯 9001

      非常简单,您甚至不需要了解 XML!

      (忽略我归因于库的速度评级。我编造了它们。)

      edit:property_tree 当然支持从 ptree 对象导出 XML。我写了一个阅读XML的例子,因为(1)它是我唯一熟悉的用法,(2)网上的例子很少。

      【讨论】:

      • 我还是觉得离题有点不好。我试图展示 ptree 如何作为类似 DOM 的容器工作。举个例子,如果你熟悉 STL,那么如何使用它来写作应该会很明显。
      • -1 因为问题不是如何解析 XML,而是如何编写 XML。
      • 很公平。但是你必须意识到 property_tree 是全新的。我怀疑很多人都熟悉它。 FWIW,你可以在末尾添加write_xml("file.xml", doc),它的功能与XML+ostream完全一样。
      【解决方案5】:

      在 cmets 中已经提到过,但我要再次提到 TinyXML。在我使用它的大约 7 年里,我从未遇到过任何问题。

      API 并不是真正地道的 C++(我自己从来没有真正为“ticpp”包装器烦恼过),但它运行良好,速度很快,而且如果您的真的很容易自己包装它不喜欢 API。

      【讨论】:

        【解决方案6】:

        我建议CodeSynthesis xsd 编译器和 C++ 树映射。

        【讨论】:

          【解决方案7】:

          大多数人会讨厌这个答案,但我习惯于手写 XML(在 C++ 中这将使用 ostream)并使用第三方库来读取 XML。

          我还没有阅读和修改 XML 的案例。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-18
            • 1970-01-01
            • 2013-05-26
            相关资源
            最近更新 更多