I know there's already a way to loop through a file with pugi::xml_node::traverse, but I'm very interested in how things work, so I want to reimplement it using a recursive function.
Currently, I can only parse the first depth of the function because I don't know how to detect whether the current item has children (next_siblings returns an invalid value).
// TODO: use std::ostringstream instead of std::string
void MyClass::recursive(const pugi::xml_node& start, std::string& output)
{
// Check for invalid node
if (!start.first_child() || (!start.next_sibling() && start.parent() != start.parent())) {
return;
}
// Process the current node
for (auto node : start.children()) {
output += node.name();
output += "\n";
for (auto attribute : node.attributes()) {
output += "Attribute Name : ";
output += attribute.name();
output += ", Attribute Value = ";
output += attribute.value();
output += " ";
}
output += "\n";
const char* PCDATA = node.child_value();
output += PCDATA == "" ? "[no pcdata]"
: PCDATA;
if (node.first_child()) {
recursive(node, output);
}
else {
recursive(node.next_sibling(), output);
}
}
}
Sample XML file
<?xml version="1.0" encoding="UTF-8"?>
<root>
<child1>
<sub name="attr1">value</sub>
<sub name="attr2">value</sub>
<sub name="attr3">value</sub>
</child1>
<child2>
<sub name="attr1">value</sub>
<sub name="attr2">value</sub>
<sub name="attr3">value</sub>
</child2>
<child3>
<sub name="attr1">value</sub>
<sub_with_children>
<child1 name="[]">value</sub>
<child2 name="[]">value</sub>
<child3 name="[]">value</sub>
</sub_with_children>
</child3>
<child4>
<sub name="attr1">value</sub>
<sub name="attr2">value</sub>
</child4>
</root>
Edit: the code above is now working