提升property_tree:在重复的子元素中遍历重复的子元素的属性

时间:2018-12-03 23:15:41

标签: xml boost boost-propertytree child-nodes

我有以下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迭代器返回的值(自身)与标准ptree之间的强制转换问题,但是我不确定其他如何检索内部子属性。我能够检索参数标签名称(通过first)和参数值(通过second.data()),而没有属性。

1 个答案:

答案 0 :(得分:2)

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

  <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