Узел RapidXML имеет правильное значение в блоке try catch, но это nullptr вне блока - PullRequest
1 голос
/ 29 октября 2019

Это может быть скорее проблема c ++, чем проблема rapidxml, и я все еще изучаю c ++, так что извините, если это очень глупый вопрос.

Я пытаюсь загрузить файл XML внутриблок try:

rapidxml::xml_document<> doc;
rapidxml::xml_node<>* root_node;
try 
{
    rapidxml::file<> file((data_folder + "\\application.xml").c_str());
    doc.parse<0>(file.data());
    root_node = doc.first_node("Application");

    std::cout << root_node->first_node("AppMeta");
}
catch (const std::runtime_error& e)
{
    // ...
}

Этот код правильно печатает указатель узла AppMeta. Проблема в том, что когда я перемещаю строку cout за пределы блока:

rapidxml::xml_document<> doc;
rapidxml::xml_node<>* root_node;
try 
{
    rapidxml::file<> file((data_folder + "\\application.xml").c_str());
    doc.parse<0>(file.data());
    root_node = doc.first_node("Application");
}
catch (const std::runtime_error& e)
{
    // ...
}

std::cout << root_node->first_node("AppMeta");

В этом случае значение, отображаемое на консоли, равно nullptr (00000000). Почему это происходит, и как я могу получить доступ к XML dom после блока try catch?

Ответы [ 2 ]

1 голос
/ 29 октября 2019

Завершение блока try также вызывает деструктор rapidxml::file<> file, поэтому вы больше не можете получить доступ к содержимому. Поскольку перемещение файла в область видимости вне блока try не сможет обнаружить ошибки конструирования, скопируйте данные в переменную с большей областью действия. rapidxml::file<>::data() просто возвращает указатель на данные, но если его больше нет, вы не можете использовать эту функцию.

Документация для класса файлов говорит: «Данные будутавтоматически уничтожается деструктором. '

rapidxml::xml_document<> doc;
rapidxml::xml_node<>* root_node;
std::string copied_data;
try 
{
    rapidxml::file<> file((data_folder + "\\application.xml").c_str());
    copied_data = file.data();
    doc.parse<0>(copied_data.c_str());
    root_node = doc.first_node("Application");
}
catch (const std::runtime_error& e)
{
    // ...
}

std::cout << root_node->first_node("AppMeta");
0 голосов
/ 29 октября 2019

Поскольку единственная цель блока try - перехватывать исключения, создаваемые этим конструктором, перемещение файла () в область видимости не было возможным. Я решил проблему, создав файл с ключевым словом new.

rapidxml::xml_document<> doc;
rapidxml::xml_node<>* root_node;
try 
{
    rapidxml::file<> *file = new rapidxml::file<>((data_folder + "\\application.xml").c_str());
    doc.parse<0>(file->data());
}
catch (const std::runtime_error& e)
{
    Utils::exitError(Utils::format("Unable to load the application data.\nDetails: %s", e.what()));
    return;
}

root_node = doc.first_node("Application");
std::cout << root_node->first_node("AppMeta")->name();
...