Windows Installer packages (.MSI) are OLE/COM Structured Storage. Microsoft provides a Win32 API ( MSI.dll ) and a COM Automation Interface ( "WindowsInstaller.Installer" ).
On Unix, much of the Win32 API has been ported to Wine.
Now I've never done this, but I see something that's promising. There is an open source project called OpenMCDF. It's written in Visual Studio / .NET but claims it supports Mono. In it is a test app (document explorer) and when you say File | Open it shows .MSI as a drop down choice so they were atleast thinking about it.
Anyway in the source code I see classes for streams and storages. Ready up on MSI's and you'll find that files are compressed into (Microsoft) CAB archives and them embedded into the MSI by inserting it into the streams.
In a situation like this I would likely create a new cabinet with the updated XML file, record it in the Media table and update the file table to reflect the new sequence number, file size and media Id.
For an MSI expert, this is trivial to do in C#. For a .NET expert, it's really hard. For someone who is neither trying to do it in PHP on CentOS... good luck.
Another approach would be to build the MSI with that one file uncompressed and then use that as a template to overwrite the file and build a self extracting EXE. That would probably be much easier for you. Just make sure the MSI and XML get cached for repair transactions.
Either that or just set up a Windows server and pass the build off to it and pick it back up when done.