1

I can turn my XML document file into object:

if(exists("generators.xml")) { //http://stackoverflow.com/a/12774387/607407
    rapidxml::file<> xmlFile("generators.xml"); // Open file, default template is char

    xml_document<> doc;               // character type defaults to char
    doc.parse<0>(xmlFile.data());;    // 0 means default parse flags
    xml_node<> *main = doc.first_node();  //Get the main node that contains everything
    cout << "Name of my first node is: " << doc.first_node()->name() << "\n";

    if(main!=NULL) {
        //Get random child node?
    }
}

I'd like to pick one random child node from the main object. My XML looks like this (version with comments):

<?xml version="1.0" encoding="windows-1250"?>
<Stripes>
  <Generator>
     <stripe h="0,360" s="255,255" l="50,80" width="10,20" />
  </Generator>
  <Generator>
     <loop>
       <stripe h="0,360" s="255,255" l="50,80" width="10,20" />
       <stripe h="0,360" s="255,255" l="0,0" width="10,20" />
     </loop>
  </Generator>
</Stripes>

I want to pick random <Generator> entry. I think getting the child count would be a way to do it:

//Fictional code - **all** methods are fictional!
unsigned int count = node->child_count();
//In real code, `rand` is not a good way to get anything random
xmlnode<> *child = node->childAt(rand(0, count));

How can I get child count and child at offset from rapidxml node?

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778

1 Answers1

3

RapidXML stores the DOM tree using linked lists, which as you'll know are not directly indexable.

So you'd basically need to implement those two methods yourself, by traversing the nodes children. Something like this (untested) code.

int getChildCount(xmlnode<> *n)
{
  int c = 0;
  for (xmlnode<> *child = n->first_node(); child != NULL; child = child->next_sibling())
  {
    c++;
  } 
  return c;
} 

getChildAt is obviously similar.

Roddy
  • 66,617
  • 42
  • 165
  • 277
  • Yeah. I have implemented functions that returns `std::vector` of children for given node. I just hoped there's a built-in functionality for this. – Tomáš Zato Dec 11 '14 at 13:01
  • @TomášZato - Only just spotted that you may be using `rapidxml_utils` which has a helper function `count_children` which does the same thing. No 'child_at' function yet, though. – Roddy Dec 11 '14 at 14:21
  • 1
    As of getting random child, [child count is actually unnecessary information](http://math.stackexchange.com/a/1058547/60941) as I have discovered. – Tomáš Zato Dec 11 '14 at 14:26
  • @TomášZato - Thanks, I never knew about that! – Roddy Dec 11 '14 at 15:17