Restoring SMS and MMS from multiple backups with Titanium Backup Pro

I got a new Nexus 4 this week - not by choice. I was fine with my Galaxy Nexus to be honest, even if it was pretty slow thanks to the misconfigured dalvik heap parameters in the 4.2 Jellybean update, and was content to wait for the next Nexus phone from Google. But alas, one fair evening my GNex stopped charging. The USB port was fine and I could still read it on my computer, it simply refused to charge the battery - not even through the car dock push pins on the side. I had to scramble to Radio Shack (and discover that they apparently are still in business precisely for these sort of situations) to buy an external battery charger just so I could continue having a phone. Since Samsung warranty service would take weeks, I bit the bullet and ordered a Nexus 4.

There are many annoyances that come with porting all your data to a new phone; personal data like call logs, SMS and MMS being a major one. Fortunately, the lovely Titanium Backup Pro has a 'backup to XML' option for SMS and MMS. However, disaster struck once I realized that when you restore, it overwrites any existing messages you may have. Why it doesn't just append to the SMS or MMS database is beyond me. This was my situation, since I had accumulated some SMS and MMS messages on my new Nexus 4 by the time I got around to migrating my GNex data. I didn't want to lose anything.

But I mentioned the files that Titanium backs up are just XML, remember? Let's dig in and see if I can't manually merge the two backup files without too much effort. Here's what their XML looks like:

Seems simple enough. SMS messages are stored as sms nodes with some metadata attributes, and MMS messages are similar, with their content stored as a pile of base64 text. Each thread node contains sms and mms objects, and there's a parent threads node that contains all the threads. That count attribute on is annoying though, let's see if I can ignore that and if just adding in the entire node from the other file will work...

Nope. Having two  objects in the same file just made Titanium take the last one in the file. I don't need to look at their XSD to guess that threads probably has maxOccurs=1 as an attribute.

Oh well. So I'll have to add in all the other  nodes into the single parent, and increase count accordingly. Let's give that a shot... bingo! Worked marvelously. Titanium didn't even care that I had thread nodes sharing the same phone number (address) - the restore process merged them correctly into one thread!

And here I was planning to get all dirty and write a python lxml monstrosity to navigate and update each child thread with sms and mms children from every backup file I had. Whew!