Я выбрал tinyxml2
для парсинга XML файлов, хочу узнать как рекурсивно обойти элементы XML.
text.XML
<data>
<data>
<username>johny1994</username>
<realname>John Batcher</realname>
</data>
<data>
<username>drdre222</username>
<realname>Doctor Dree</realname>
</data>
</data>
data
- первый XML элемент, за ним следует дочерний data
элемент, за дочерним data
следуют дочерние username
и realname
.
Дочерних data
которые идут от корневого отца элемента data
может быть N количество (в моем случае 2). Нужно найти все эти дочерние data
элементы и пройтись по ним рекурсивно.
Код:
tinyxml2::XMLDocument doc;
tinyxml2::XMLError e = doc.LoadFile("text.xml");
if (e != tinyxml2::XML_SUCCESS) {
std::cout << "Error load file" << std::endl;
}
auto root = doc.FirstChildElement("data");
if (root == nullptr)
{
std::cout << "Child element not found\n";
}
// Тут должен быть какой-то код типа цикла для обработка data элементов
// что-то типа for (root; root < elementCount; ++root) {};
auto rootdata = root->FirstChildElement("data");
if (rootdata == nullptr)
{
std::cout << "Child (data) element not found\n" << std::endl;
}
auto username = rootdata->FirstChildElement("username");
if (username == nullptr)
{
std::cout << "username is null ptr" << std::endl;
}
std::cout << "Username:\t" << username->GetText() << std::endl;
auto realname = rootdata->FirstChildElement("username");
if (realname == nullptr)
{
std::cout << "realname is null ptr" << std::endl;
}
std::cout << "Real name:\t" << realname->GetText() << std::endl;
Вывод должен быть примерно следующим:
Username: johny1994
Real name: John Batcher
Username: drdre222
Real name: Doctor Dre
Обычно рекурсию используют для продвижения вглубь дерева (от корня к листам). Не понимаю, зачем Вам рекурсивно пробегать по элементам одного уровня, по которым гораздо удобнее пройтись циклом:
auto root = doc.FirstChildElement("data");
if (root == nullptr)
{
std::cout << "Child element not found\n";
}
// Тут должен быть какой-то код типа цикла для обработка data элементов
auto current_data = root->FirstChildElement("data");
auto last_data = root->LastChildElement("data");
do
{
if (current_data == nullptr)
{
std::cout << "Child (data) element not found\n" << std::endl;
break;
}
auto username = current_data->FirstChildElement("username");
if (username == nullptr)
{
std::cout << "username is null ptr" << std::endl;
break;
}
std::cout << "Username:\t" << username->GetText() << std::endl;
auto realname = current_data->FirstChildElement("username");
if (realname == nullptr)
{
std::cout << "realname is null ptr" << std::endl;
break;
}
std::cout << "Real name:\t" << realname->GetText() << std::endl;
current_data = current_data->NextSibling();
}
while(current_data != last_data);
вот пример рекурсии:
void Recursion(const XMLNode* root, const XMLNode* current_data)
{
if (current_data == nullptr)
{
std::cout << "Child (data) element not found\n" << std::endl;
return;
}
auto username = current_data->FirstChildElement("username");
if (username == nullptr)
{
std::cout << "username is null ptr" << std::endl;
return;
}
std::cout << "Username:\t" << username->GetText() << std::endl;
auto realname = current_data->FirstChildElement("username");
if (realname == nullptr)
{
std::cout << "realname is null ptr" << std::endl;
return;
}
std::cout << "Real name:\t" << realname->GetText() << std::endl;
current_data = current_data->NextSibling();
if(current_data != root->LastChildElement("data"))
{
Recursion(root, current_data->NextSibling());
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Очень нужно собрать проект (библиотеки и исполняемые файлы) на Qt в виндовсе на линуксНашел в интернете про сборку с линукса на виндовс, но ничего...
Как можно узнать размер динамического массива, например int* или как получить указатель на его конец