【问题标题】:boost property_tree: iterating through attributes of repeated child elements within repeated child elementsboost property_tree:遍历重复子元素中重复子元素的属性
【发布时间】:2018-12-03 23:15:41
【问题描述】:

我有以下 XML 文档:

<root>
  <scenario name="ScenarioA">
    <param name="ParamA">1</param>
    <param name="ParamB">2</param>
    <param name="ParamC">3</param>
  </scenario>
  <scenario name="ScenarioB">
    <param name="ParamA">1</param>
    <param name="ParamB">2</param>
    <param name="ParamC">3</param>
  </scenario>
  <scenario name="ScenarioC">
    <param name="ParamA">1</param>
    <param name="ParamB">2</param>
    <param name="ParamC">3</param>
  </scenario>
</root>

使用boost::property_tree::ptree,我可以执行以下操作来遍历顶级元素:

ptree scenarioTree = myTree.get_child("root");
for (const auto& itr : scenarioTree) {
    if (itr.second.get<std::string>(<xmlattr>.name) == "ScenarioA") {
        // additional logic
    }
}

我无法在每个场景下使用itr.second上的相同方法检索“param”标签的任何属性:

ptree scenarioTree = myTree.get_child("root");
for (const auto& itr : scenarioTree) {
    if (itr.second.get<std::string>(<xmlattr>.name) == "ScenarioA") {
        ptree paramTree = itr.second;
        // Iterate through "param" tags
        for (const auto& paramItr: paramTree) {
            if (paramItr.second.get<std::string>(<xmlattr>.name) == "ParamA") {
                // doesn't exist
            }
        }
    }
}

我做错了什么?我的理论是这是 ptree 迭代器返回(self)与标准 ptree 之间的转换问题,但我不确定如何检索内部子属性。我能够检索参数标记名称(通过 first)和参数值(通过 second.data()),只是没有属性。

【问题讨论】:

    标签: xml boost boost-propertytree child-nodes


    【解决方案1】:

    属性树中的属性被添加为子节点。 下面的节点可以翻译

      <scenario name="ScenarioA">
        <param name="ParamA">1</param>
        <param name="ParamB">2</param>
        <param name="ParamC">3</param>
      </scenario>
    

    变成这样:

      scenario 
         xmlattr.name   ScenarioA // this node doesn't have subnode with attribute name
         param 
           xmlattr.name  -> ParamA
         param 
           xmlattr.name  -> ParamB
         param 
           xmlattr.name  -> ParamC
    

    当您找到以ScenarioA 作为属性的场景时,您正在迭代其子级。该节点有 4 个子节点。对于您要查找name 属性的每个孩子,但其中一个没有此属性。找不到路径时,方法get 抛出异常。您可以捕获此异常或使用默认值:

    boost::property_tree::ptree scenarioTree = pt.get_child("root");
    for (const auto& itr : scenarioTree) 
    {
        if (itr.second.get<std::string>("<xmlattr>.name") == "ScenarioA") 
        {
            boost::property_tree::ptree paramTree = itr.second;
            for (const auto& paramItr: paramTree) 
            {
                if (paramItr.second.get<std::string>("<xmlattr>.name","") == "ParamA") 
                {                                                    ^^^^ default value
                    cout << "ParamA was found in ScenarioA" << endl;
                }
            }
        }
    }
    

    结果我得到了在场景A中找到了Parama

    【讨论】:

    • 非常感谢。现在这很有意义,我想知道是否缺少属性,但是我的整体 try/catch 在第一次(空)尝试时停止了迭代。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    相关资源
    最近更新 更多