Xml element duplication woes

I’m in that horrible sinking sand where I’ve spent hours stuck and trying everyway I can think of.

    juce::XmlElement test = *branchPresetsRoot->getChildElement(0);
    branchPresetsRoot->insertChildElement(&test, i);

This doesn’t work as it triggers a malloc error at the insert. I’m pretty sure the 1st line is a deep copy? just how to add the bloody thing back to the xml.

If anyone can point me in the right direction it would be appreciated & my feature request for XmlElement is a simple duplicate child member function.

I really hope someone can shine some light on how to solve this, here’s another failed example:

    juce::XmlElement newDevicePresets("BranchPresets");
    newDevicePresets.addChildElement(branchPresetsRoot->getChildElement(0));

But, this is a reference and so can not be added to another node:

error → // The element being added must not be a child of another node!
jassert (newNode->nextListItem == nullptr);

So I need a deep copy, but it seems impossible to make one that can be accepted by addChild/insertChild.

another method I tried was converting the desired element toString() and then an XmlDoc but the resulting parse returns a unique_ptr which isn’t accepted by these add/insert functions and so lands me right back in the same place of not being able to add a child that belongs to a different structure.

It can’t be this hard to simply duplicate a child element?

Your initial code has the element made on the stack, so will be destroyed at the end of the scope, leaving the element as a pointer to junk memory. It should work if you do that same thing but on the heap, eg

XmlElement* copy = new XmlElement(otherXml);

At least I think, I’m on my phone and can’t check in too much depth atm!

1 Like

So the docs say…

make sure the object that you pass in will not be deleted by anything else, and make sure it’s not already the child of another element.

In your first example, the test object will be deleted when it goes out of scope. In your second example you’re adding a child that is a child of another element.

When you call add/insert/prependChildElement you must give it an owning pointer because…

Child elements are deleted automatically when their parent is deleted

So without actually testing this, you could try something like…

if (const auto* child = root->getChildElement (0))
{
    auto copyOfChild = std::make_unique<juce::XmlElement> (*child);
    root->addChildElement (copyOfChild.release());
}

Hope that helps.

1 Like

Thanks, that works. I presumed because the xml structure is loaded from file & saved at the end of this single function that lifetime wouldn’t be an issue.

Thankyou both for the help, I couldn’t move forward until that issue was solved!