使用 Boost C++ 为嵌套标签解析 xml

Posted

技术标签:

【中文标题】使用 Boost C++ 为嵌套标签解析 xml【英文标题】:Parsing xml using Boost c++ for nested tags 【发布时间】:2018-01-17 14:31:29 【问题描述】:

我正在尝试使用具有以下结构的 boost 解析 xml 文件:

<root> 
  <chocos> 
    <choco>
      <color>1</color>
    <companies>
      <comapany>10</company>
      <comapany>11</company>
    </companies>
  </choco>
  <choco>
    <color>2</color>
    <companies>
      <comapany>12</company>
      <comapany>13</company>
    </companies>
   </choco>
 </chocos>
</root>

我需要将其存储在以下类中:

class root_info

   public:
      //some members
      std::vector<choco_info> chocos;


class choco_info

   int color;
   int companies[100];

我写了以下代码,但它显示错误:

没有这样的节点(公司)读取xml文件失败>

代码:

  for(const auto& v : pt.get_child("root.chocos"))
  
     choco_info choco;
     if(v.first == "choco")
     
        choco.color = v.second.get<unsigned>("color");
        int i = 0;
        for(const auto& v2 : pt.get_child("companies"))
        
           if( v2.first == "company")
           
              choco.company[i] = v2.second.get<unsigned>("company");
              i++;
           
        
     
     root.chocos.push_back(choco);
  

xml 无法更改,因为它已提供给我。主要问题在于如何迭代“chocos”以及“companies”

【问题讨论】:

pt.get_child("companies") 在我看来很可疑。不应该是v.second.get_child("companies") 你甚至没有提到你正在使用什么 boost 库。 @drescherjm:我做了那个改变。它现在显示下一个节点(即“公司”)的相同错误。这是访问该节点的错误方式吗? @drescherjm:知道了!我需要写 v2.first == "companies" 。 【参考方案1】:

结构化代码有助于降低复杂性:

Live On Coliru

#include <boost/property_tree/xml_parser.hpp>

std::string const sample = R"(<root> 
  <chocos> 
    <choco>
      <color>1</color>
    <companies>
      <comapany>10</company>
      <comapany>11</company>
    </companies>
  </choco>
  <choco>
    <color>2</color>
    <companies>
      <comapany>12</company>
      <comapany>13</company>
    </companies>
   </choco>
 </chocos>
</root>)";

using boost::property_tree::ptree;

using companies_t = std::vector<int>;

struct choco_info 
   int color;
   companies_t companies;
;

using chocos_t = std::vector<choco_info>;

struct root_info 
    //some members
    chocos_t chocos;
;

bool read_companies(ptree const& pt, companies_t& into) 
    for (auto& [name,child] : pt)
        if (name == "comapany") // FIXME
            into.push_back(child.get_value<int>());
        else 
            return false;
    return true;

bool read_chocos(ptree const& pt, chocos_t& into) 
    for (auto& [name,child] : pt) 
        if (name == "choco") 
            choco_info ci;
            ci.color = child.get("color", -1);
            if (!read_companies(child.get_child("companies"), ci.companies))
                return false;

            into.push_back(std::move(ci));
         else 
            return false;
        
    
    return true;


#include <iostream>

int main() 
    ptree pt;
    
        std::istringstream iss(sample);
        read_xml(iss, pt);
    

    root_info result;

    bool ok = true;
    try 
        ok = read_chocos(pt.get_child("root.chocos"), result.chocos);
     catch(std::exception const& e) 
        std::cout << "Exception: " << e.what() << "\n";
        ok = false;
    

    if (ok) 
        std::cout << "Parsed:\n";
        for (auto& choco : result.chocos) 
            std::cout << " - color " << choco.color << "\n";
            for (int company : choco.companies)
                std::cout << "   * company " << company << "\n";
        
     else 
        std::cout << "Error in input\n";
    

打印

Parsed:
 - color 1
   * company 10
   * company 11
 - color 2
   * company 12
   * company 13

【讨论】:

我是编译错误:在函数'bool read_companies(const ptree&,company_t&)'中:错误:在'['令牌之前预期的不合格ID(auto&[name,child]:pt)预期' ;' 在 ':' 标记之前 与 read_chocos 函数类似。还显示“‘name’未在此范围内声明”和“‘child’未在此范围内声明” 我已经检查过了,我没有遗漏任何分号或其他需要的标记。

以上是关于使用 Boost C++ 为嵌套标签解析 xml的主要内容,如果未能解决你的问题,请参考以下文章

C++ BOOST库解析XML文件的问题

c++ boost xml解析器ptree.get函数——不接受节点名中的空格

如何将动态XML中的嵌套标签转换为for循环?

使用属性树在 boost 中解析 xml

c ++如何使用boost xml解析器读取XML并存储在地图中

C++的Json解析库:jsoncpp和boost(转)