boost property_tree: перебирая атрибуты повторяющихся дочерних элементов внутри повторяющихся дочерних элементов - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть следующий 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
    }
}

Я не могучтобы получить любые атрибуты тегов "param" в каждом сценарии, используя один и тот же метод для itr.second:

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, но я не уверен, как еще получить внутренние дочерние атрибуты.Я могу получить имена тегов param (через first) и значения параметров (через second.data ()), только без атрибутов.

1 Ответ

0 голосов
/ 04 декабря 2018

Атрибуты в дереве свойств добавляются как подузлы.Нижний узел может быть переведен

  <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;
            }
        }
    }
}

в результате я получил ParamA был найден в сценарии A .

...