c++xmlrapidxml

Rapidxml next_sibling not return the next sibling


I want to select the "actual" xml node by attribute.

When I try to iterate trough the nodes, it only return the first one, but strangely, when I ask the last node, it will return it without any problem. Also, if I search it with name like "actualroot->first_node("roodnode1")" it will found it. edit: I checked it just in case and the "actualroot" have parent

Rapidxml version: 1.13 (I tried different version too(1.1), and it had the same result)

The saved xml:

<rootnode Game="gamename">
    <rootnode0 table="a" cluster="b" item="c"/>
    <rootnode1 table="atest" cluster="btest" item="ctest"/>
    <rootnode2 table="1" cluster="2" item="3"/>
</rootnode>

The simplified verion of the code I use:

#include "rapidxml.hpp"
#include "rapidxml_print.hpp"


using namespace std;
using namespace rapidxml;

bool listloaded;
bool actualcontainerloaded;
int rootcounter;
xml_document<> *actuallist;
xml_node<>* actualroot;
xml_node<>* actualcontainer;
std::unordered_map<std::string, xml_document<>*> xmllistmap;

main()
{
listloaded = false;
actualcontainerloaded = false;
rootcounter = 0;

create("tastx")
addcontainer("a","b","c")
addcontainer("atest","btest","ctest")
addcontainer("1","2","3")
setactualcontainer("atest","btest","ctest")
}


bool create(string name)
{
   if (isalreadyexist(name)) return false;
   //RPXdata oneRPX;
   xml_document<> *newlist = new xml_document<>(); 
   xml_node<>* root = newlist->allocate_node(node_element, newlist->allocate_string("rootnode"));
   root->append_attribute(newlist->allocate_attribute("Game", newlist->allocate_string("gamename")));
   newlist->append_node(root);
   newlist->name(name.c_str());
   xmllistmap[name] = newlist;
   actuallist = newlist;
   actualroot = newlist->first_node();
   listloaded = true;
   return true;
}




bool addcontainer(string table, string cluster, string item)
{
    if (listloaded)
    {
        
        for (xml_node<> *child = actualroot->first_node(); child; child = actualroot->next_sibling())
        {
            
            if (child->first_attribute("table") == NULL) continue;
            string tableattr = child->first_attribute("table")->value();
            if (tableattr != table) continue;
            if (child->first_attribute("cluster") == NULL) continue;
            string clusterattr = child->first_attribute("cluster")->value();
            if (clusterattr != cluster) continue;
            if (child->first_attribute("item") == NULL) continue;
            string itemattr = child->first_attribute("item")->value();
            if (itemattr == item) continue;
            return false;
        }
        string rootname = "rootnode"+functions.converttostring(rootcounter);
        xml_node<>* root = actuallist->allocate_node(node_element, actuallist->allocate_string(rootname.c_str()));
        root->append_attribute(actuallist->allocate_attribute("table", actuallist->allocate_string(table.c_str())));
        root->append_attribute(actuallist->allocate_attribute("cluster", actuallist->allocate_string(cluster.c_str())));
        root->append_attribute(actuallist->allocate_attribute("item", actuallist->allocate_string(item.c_str())));
        actualroot->append_node(root);
        functions.log("container added:" + table);
        rootcounter++;
    }

    return false;
}


bool setactualcontainer(string table, string cluster, string item)
{
    if (listloaded)
    {
        for (xml_node<> *child = actualroot->first_node(); child; child = actualroot->next_sibling())
        {
            xml_node<> *lastchild = actualroot->last_node();
            string lcname = lastchild->name();
            functions.log("last name: " + lcname);
            string cname = child->name();
            functions.log("cname: " + cname);
            functions.log("for step called");
            if (child->first_attribute("table") == NULL) continue;
            string tableattr = child->first_attribute("table")->value();
            string clusterattr = child->first_attribute("cluster")->value();
            string itemattr = child->first_attribute("item")->value();
            functions.log("actual tableattr:" + tableattr);
            
            if (tableattr == table && clusterattr == cluster && itemattr == item)
            {
                functions.log("actual continer settd:"+ table);
                actualcontainer = child;
                actualcontainerloaded = true;
                return true;
            }
            
        }
        
    }
    return false;
}

The result:

23:11:17: container added:a
23:11:17: container added:atest
23:11:17: container added:1
23:11:17: last name: rootnode2
23:11:17: cname: rootnode0
23:11:17: for step called
23:11:17: actual tableattr:a

Solution

  • Just a simple inattention: The for loop

    for (xml_node<> *child = actualroot->first_node(); child; child = actualroot->next_sibling())
    
    

    actually should looks like this:

    for (xml_node<> *child = actualroot->first_node(); child; child = child->next_sibling())