перебирать дерево свойств наддува - PullRequest
4 голосов
/ 09 февраля 2012

Я перебираю XML-документ, используя дерево свойств boost и сохраняю результаты в структуре.Проблема, с которой я столкнулся, заключается в том, что я могу добраться только до первых узлов "item" и не могу получить доступ ко вторым узлам "item".Я надеялся, что кто-то укажет, где я допустил ошибку.

Вывод моей программы выглядит следующим образом (вы можете видеть, что элементы отсутствуют ... элементов cookie2, candy2 или chocolate2 не показано):

jar : snAcks
snack : coOkie
item : cooKie1
snack : canDy
item : caNdy1
snack : cHocolate
item : choColate1

Вот XML-файл:

<root>
    <jar name="snAcks">
        <snack name="coOkie">
           <item name="cooKie1"></item>
           <item name="cookIe2"></item>
        </snack>
        <snack name="canDy">
           <item name="caNdy1"></item>
           <item name="candY2"></item>
        </snack>
        <snack name="cHocolate">
           <item name="choColate1"></item>
           <item name="chocOlate2"></item>
        </snack>
    </jar>
</root>

Вот исходный код:

void parse_xml( boost::property_tree::iptree const& pt )
{
    BOOST_FOREACH( boost::property_tree::iptree::value_type const& v, pt.get_child("root.jar") )
    {
        // Show jar
        if ( boost::iequals( v.first, "<xmlattr>" ) )
        {
            std::cout << "jar : " << v.second.get<std::string>("NaME") << std::endl;
        }

        if ( boost::iequals( v.first, "snack" ) )
        {
            // Show snack
            std::cout << "snack : " << v.second.get<std::string>("<xmlattr>.name")  << std::endl;

            try
            {
                BOOST_FOREACH( boost::property_tree::iptree::value_type const& val, v.second.get_child("item") )
                {
                    if ( boost::iequals( val.first, "<xmlattr>" ) ) {
                        // Show item
                        std::cout << "item : " << val.second.get<std::string>("nAmE")  << std::endl;
                    }
                }
            }

            catch (boost::property_tree::ptree_bad_path& e)
            {
                // Show what caused exception
                std::cout << "Exception: " << e.what() << std::endl;
            }
        }
    }
}

Спасибо, что нашли время, чтобы прочитать это.Я думаю, что совершил простую ошибку, но не могу понять, где.

1 Ответ

9 голосов
/ 03 марта 2012

Я понял это, но это не то, что я бы назвал интуитивно понятной библиотекой xml-анализатора.

void parse_xml( boost::property_tree::iptree const& pt )
{
    BOOST_FOREACH(boost::property_tree::iptree::value_type const& v, pt.get_child("root.jar"))
    {
        // Show jar
        if ( boost::iequals( v.first, "<xmlattr>" ) ) {
            std::cout << "jar : " << v.second.get<std::string>("NaME") << std::endl;
        }

        if ( boost::iequals( v.first, "snack" ) )
        {
            BOOST_FOREACH(boost::property_tree::iptree::value_type const& val, v.second)
            {
                // Show snack
                if ( boost::iequals( val.first, "<xmlattr>" ) ) {
                    std::cout << "snack : " << val.second.get<std::string>("name")  << std::endl;
                }

                if ( boost::iequals(val.first, "item") )
                {
                    BOOST_FOREACH(boost::property_tree::iptree::value_type const& val2, val.second)
                    if ( boost::iequals( val2.first, "<xmlattr>" ) ) {
                        // Show item
                        std::cout << "item : " << val2.second.get<std::string>("nAmE")  << std::endl;
                    }
                }
            }
        }
    }
}

Если вы сравните два фрагмента кода, вы увидите, что мой немного структурирован более регулярно.

  1. Цикл по всем узлам
  2. обработка <xmlattr> узла
  3. обработка "реального" узла.
  4. повторение с шага 1. внутрьэтот узел.
...