Обход простого документа DOM Xml с использованием RapidXML

Итак, ребята, я использую RapidXML для разбора очень простого XML-документа. Все, что я пытаюсь сделать, это проанализировать данные из XML-документа в мою собственную структуру данных. В качестве отправной точки я хотел бы иметь возможность выводить каждый узел, и данные содержатся, кроме того, я думаю, что смогу это понять. Документация для rapidXML, по-видимому, в основном сосредоточена на создании XML-документов с использованием RapidXML, однако здесь я просто пытаюсь ее прочитать. Для начала вот мой код (в качестве примечания, прежде чем я продолжу работу с этой программой, я, конечно, загружу xml прямо из файла, не шутите!)

#include <cstdlib>
#include <iostream>
#include "Page.h" 
#include "HashTable.h"
#include "TimeStamp.h"
#include "AvlTree.h"
#include "./rapidxml/rapidxml.hpp"
#include "./rapidxml/rapidxml_print.hpp"
#include <fstream>
#include <sstream>
#include <vector>


using namespace std;
using namespace rapidxml;

char s[] = "<?xml version='1.0' encoding='utf-8'?>"
    "<people>"
        "<person gender='female'>"
            "<fname>Morgan</fname>"
            "<lname>Saxer</lname>"
        "</person>"
        "<person gender='male'>"
            "<fname>Tyler</fname>"
            "<lname>Springer</lname>"
        "</person>"
    "</people>";

void traverse_xml(const std::string& input_xml)
{
    vector<char> xml_copy(input_xml.begin(), input_xml.end());
    xml_copy.push_back('\0');

    xml_document<> doc;
    doc.parse<parse_declaration_node | parse_no_data_nodes>(&xml_copy[0]);

    string encoding = doc.first_node()->first_attribute("encoding")->value();
    cout << "encoding: " << encoding << endl;

    xml_node<>* cur_node = doc.first_node("people");

    string person_type = cur_node->first_node("person")->first_attribute("gender")->value();
    cout << "Gender: " << person_type << endl;

    cur_node = cur_node->first_node("person")->first_node("fname");
    string attr2 = cur_node->value();
    cout << "fname: " << attr2 << endl;

    cur_node = cur_node->next_sibling("lname");
    attr2 = cur_node->value();
    cout << "lname: " << attr2 << endl;

    //next person node begins here, this is where I am having the problem

    cur_node = cur_node->next_sibling("person"); //this doesn't work, and I don't know what command to use instead
    attr2 = cur_node->first_attribute("gender")->value();
    cout << "Gender: " << attr2 << endl;
}

int main(int argc, char** argv) {

   traverse_xml(s);
       return 0;
}

Тем не менее, вывод, который я получаю, таков:

encoding: utf-8 
gender: female
fname: Morgan
lname: Saxer

и это все. То, что я ищу, это:

encoding: utf-8
gender: female
fname: Morgan
lname: Saxer
gender: male

так как это будет началом узла следующего человека.

По сути, я думаю, что мой вопрос можно свести к этому. Есть ли какая-то функция "на один уровень выше" для rapidXML? Я понимаю, что next_sibling() переводит вас к следующему узлу на том же уровне, но как только вы углубляетесь в любой узел, кажется, нет очевидного способа вернуться обратно. Кто-нибудь знает, как сделать такую ​​​​вещь?

EDIT:
После использования предложенного решения мой код теперь выглядит так:

 void traverse_xml(const std::string& input_xml)
 {
    vector<char> xml_copy(input_xml.begin(), input_xml.end());
    xml_copy.push_back('\0');

    xml_document<> doc;
    doc.parse<parse_declaration_node | parse_no_data_nodes>(&xml_copy[0]);

    xml_node<>* people = doc.first_node("people");
    xml_node<>* person = people->first_node("person");

    while (person != NULL)
    {
      cout << "Gender:" << person->first_attribute("gender")->value() << endl;
      cout << "fname: " << person->first_node("fname")->value() << endl;
      cout << "lname: " << person->first_node("lname")->value() << endl;
      person = person->next_sibling("person");
    }
 }

и теперь правильно выводит следующее:

gender:female
fname: Morgan
lname: Saxer
gender:male
fname: Tyler
lname: Springer

person MS-DDOS    schedule 18.11.2012    source источник


Ответы (1)


Вы можете использовать cur_node->parent(), чтобы подняться на уровень выше, но лично я бы порекомендовал вместо этого что-то вроде этого: -

 xml_node<>* people = doc.first_node("people");
 xml_node<>* person = people->first_node("person");

 while (person != NULL)
 {
  ... output the person
  person = person->next_sibling("person"); 
 } 
person Roddy    schedule 18.11.2012
comment
идеально. Я только начал играть с RapidXML прошлой ночью, так что мне еще предстоит потратить достаточное количество времени на игры с дизайном, это здорово. Большое спасибо! - person MS-DDOS; 19.11.2012