I want to append attributes to each node found in a root tag in an iterator, and I want the attribute to be id
with indices assigned to them. Here is the block of code used for iterating over the child nodes, allocating and appending each attribute to each node:
for (xml_node<>* node = root->first_node("lang")->first_node("strings")->first_node();
node; node = node->next_sibling())
{
node->append_attribute(
document.allocate_attribute(
"id", (std::to_string(index)).c_str()
)
);
index += 1;
}
After inspection, it seems that document.allocate_attribute
isn't creating a new pointer as I expected it to, since the most of the id
attributes in the XML output produced by my function print_document
, show mostly duplicate values, i.e.:
<translations>
<lang>
<strings>
...
<s id="895">string1</s>
<s id="895">string2</s>
<s id="895">string3</s>
...
</strings>
</lang>
</translations>
print_document
is simply:
void print_document(xml_document<> &document)
{
rapidxml::print(std::cout, document, 0);
}
Given that I'm not overly concerned with memory usage, how can I ensure that each appended attribute value is unique?
This is a classic stumble due to RapidXML's string ownership design.
When you add an attribute, RapidXML doesn't make a copy of the attribute string - it just stores the pointer, which then goes out of scope and frequently gets reused for the next attribute...
Use allocate_string
to help you.
Try this:-
document.allocate_attribute("id", allocate_string(std::to_string(index).c_str()))