I'm looking to add new elements with data to the middle of my XML structure. How can I append them where I need them?
Current code:
XMLElement *node = doc.NewElement("timeStamp");
XMLText *text = doc.NewText("new time data");
node->LinkEndChild(text);
doc.FirstChildElement("homeML")->FirstChildElement("mobileDevice")->FirstChildElement("event")->LinkEndChild(node);
doc.SaveFile("homeML.xml");
And an example part of my XML structure:
<mobileDevice>
<mDeviceID/>
<deviceDescription/>
<units/>
<devicePlacement/>
<quantisationResolution/>
<realTimeInformation>
<runID/>
<sampleRate/>
<startTimeStamp/>
<endTimeStamp/>
<data/>
</realTimeInformation>
<event>
<mEventID/>
<timeStamp/>
<data/>
<support/>
</event>
</mobileDevice>
I'm looking to add it addtional timeStamp
tags under mobileDevice->event
between mEventID
and data
, at the moment they are being appended after the support
tag how can I get them to be entered in the correct place?
Current placement when ran:
<mobileDevice>
<mDeviceID/>
<deviceDescription/>
<units/>
<devicePlacement/>
<quantisationResolution/>
<realTimeInformation>
<runID/>
<sampleRate/>
<startTimeStamp/>
<endTimeStamp/>
<data/>
</realTimeInformation>
<event>
<mEventID/>
<timeStamp/>
<data/>
<support/>
<timeStamp>new time data</timeStamp>
</event>
</mobileDevice>
You want to use InsertAfterChild()
to do this. Here's an example which should do what you want (assuming that "mobileDevice" is your document's root element):
// Get the 'root' node
XMLElement * pRoot = doc.FirstChildElement("mobileDevice");
// Get the 'event' node
XMLElement * pEvent = pRoot->FirstChildElement("event");
// This is to store the element after which we will insert the new 'timeStamp'
XMLElement * pPrecedent = nullptr;
// Get the _first_ location immediately before where
// a 'timeStamp' element should be placed
XMLElement * pIter = pEvent->FirstChildElement("mEventID");
// Loop through children of 'event' & find the last 'timeStamp' element
while (pIter != nullptr)
{
// Store pIter as the best known location for the new 'timeStamp'
pPrecedent = pIter;
// Attempt to find the next 'timeStamp' element
pIter = pIter->NextSiblingElement("timeStamp");
}
if (pPrecedent != nullptr)
{
// Build your new 'timeStamp' element,
XMLElement * pNewTimeStamp = xmlDoc.NewElement("timeStamp");
pNewTimeStamp->SetText("Your data here");
// ..and insert it to the event element like this:
pEvent->InsertAfterChild(pPrecedent, pNewTimeStamp);
}
This is an interesting and probably common use case. I wrote a TinyXML2 tutorial a couple of months ago, so I'll add this to it.