How to create xml nodes in a file.

I’ve done a lot of research on this, and as far as I can tell, there’s only two ways to do it:

  1. Create the ENTIRE file manually in the form of a FString buffer.
  2. Using const_cast to remove the const from a pointer.

Option number one is a non-starter. If I have to do that, I’m using TinyXml2.

Option number two is better… slightly. One should never use const_cast if it can be avoided. Changing a variable that’s supposed to be const can lead to unexpected results (and therefore crashes). It seems to work fine for now, and can even save the FXmlFile to a file on the disk, but who knows what future results will be.

Why do I have to use const_cast? Because there’s no way to get the child/next node without it being const.

//From XmlNode.h
const FXmlNode* GetNextNode() const;
const FXmlNode* GetFirstChildNode() const;

There are no overloaded non-const functions to get them. Creating a child node doesn’t return anything:

//From XmlNode.h
void AppendChildNode(const FString& InTag, const FString& InContent);

The only way to get it would be to loop through to the last child node and grab it, but that gives me the original problem of const pointers, so I ended up using const_cast so I can forcibly manipulate them.

FXmlNode* nextNode = const_cast<FXmlNode*>(node->GetNextNode());

But that’s about the nastiest thing a programmer can do. This can lead to extreme problems if the nodes aren’t expecting values to change. It seems to work, but there’s not guarantee it’ll continue to work.

My question is: “Is there another way to do this that I haven’t found yet?”

There’s two ways you can do it.

  1. Use const_cast (like I did)
  2. Use “FindChildNode” since it actually DOES have an overloaded non-const function. This method, however, doesn’t allow you to put next nodes.

To piggyback off of this question, does this mean there is no way to add a child node to a child node? I can’t find any way to do:

<rootnode>
  <childnode>
    <grandchildnode />
  <childnode>
</rootnote>

Unfortunately, using const_cast results in a crash (using either AppendChildNode or SetContent), and using FindChildNode wouldn’t allow for two child nodes like so:

<root>
  <child>
    <grandchild/>
  </child>
  <child>
    <grandchild/>
  </child>
</root>

EDIT: I found the workaround to this is with the GetChildrenNodes(); method.

If you want to do as I did above, the code is as follows:

			// Add a new child node

			RootNode->AppendChildNode(FString("child"), FString(" "));

			// Get the array of all child nodes

			TArray<FXmlNode*> ChildNodes = RootNode->GetChildrenNodes();

			// Get new child node

			FXmlNode* NewChildNode = ChildNodes[ChildNodes.Num() - 1];

			// Add a grandchild node to the new child node

			NewChildNode->AppendChildNode(FString("grandchild"), FString("  "));

			// Get the array of all grandchild nodes

			TArray<FXmlNode*> GrandchildNodes = NewChildNode->GetChildrenNodes();

			// Get the new grandchild node

			FXmlNode* NewGrandchildNode = GrandchildNodes[GrandchildNodes.Num() - 1];

Using const_cast made you crash? Really? Worked fine for me. Even adding several great-grand child nodes in different paths.