Including the xml in the Normal.dotm is not a good idea for all the same reasons we avoid doing things to that template. It might work for the developer but only for new documents that they create - not for legacy docs, nor for anyone else creating documents.
Doing this with a global template is overthinking the problem. We can use a simple attached dotx template. Going to a global template introduces a series of problems which need to be solved by macros - hence moving to dotm. If you want to insert building blocks with mapped CCs to existing documents you need to make sure the page setup and style definition match as well as worrying about the xml.
If you want to do it the hard way with global templates then use a macro which checks to see if the xml is already there and if not, creates it. In your template you used Greg Maxey's tool to create the xml from the CC titles. If you then run that same code on a legacy document you inserted the building block into, you will recreate the xml that the CCs need.
If you wanted to avoid Greg's tool, you could include code in your global template to ensure the xml exists. Something like this would work to create the necessary fields. Note that it will wipe any existing data already in CCs so it would be better to run it before the user has populated them. If you decided to retain the xml file if it already exists, for completeness you should also check each individual field is already there as well.
Code:
Sub TestAddCustomPart()
AddCustomPart
End Sub
Function AddCustomPart(Optional sNS As String) As Office.CustomXMLPart
'Replaces/Creates the standard CustomXmlPart
Dim oXMLPart As Office.CustomXMLPart, sXML As String
Dim arrElements() As String, iElement As Integer, sFields As String
If sNS = "" Then sNS = csNamespace
For Each oXMLPart In ActiveDocument.CustomXMLParts
'Debug.Print oXMLPart.NamespaceURI 'oXMLPart.Xml
If oXMLPart.NamespaceURI = sNS Then
Debug.Print oXMLPart.XML
oXMLPart.Delete '---- or exit the macro because it already exists ----
End If
Next
sFields = "ProjectID,ProjectName,ProjectNameShort,ProjectPhase,ContractNumber,ContractName,Client,VolumeNumber,VolumeName,DocumentID,DataItemNumber,DocumentTitle"
arrElements = Split(sFields, ",")
For iElement = LBound(arrElements) To UBound(arrElements)
sXML = sXML & " <" & arrElements(iElement) & " />" & vbCr
Next iElement
sXML = "<?xml version='1.0' encoding='utf-8'?>" & vbCr & "<Root xmlns='" & sNS & "'>" & vbCr & sXML & "</Root>"
Set AddCustomPart = ActiveDocument.CustomXMLParts.Add(sXML)
Debug.Print AddCustomPart.XML
End Function
And looking back at the original question, I STILL think that mail merge filtered to a single record for 30 different documents is not a better solution. But I do recognise that if you increase the complexity of the solution (like insisting on global templates), mail merge may indeed become the best method.