The original format is not valid XML because it has 2 root nodes, so I've loaded the file using the standard Scripting.FileSystemObject to prevent any errors from XML parse errors
Option Explicit
dim fso: set fso = CreateObject("Scripting.FileSystemObject")
dim stream: set stream = fso.OpenTextFile("input.xml")
dim xml: xml = stream.ReadAll()
stream.close
To manipulate the XML, I load it into an MSXML2.DomDocument with a dummy root node so it's well-formed
dim xmldoc: set xmldoc = CreateObject("MSXML2.DomDocument")
xmldoc.setProperty "SelectionLanguage", "XPath"
xmldoc.async = false
if not xmldoc.loadXML("<root>" & xml & "</root>") then
WScript.Echo xmldoc.parseError.reason
WScript.Quit
end if
Then I use XPath to query the payments node (assuming only one) and the payment nodes (assuming more than one)
dim paymentsNode: set paymentsNode = xmldoc.selectSingleNode("//payments")
dim paymentNodes: set paymentNodes = xmldoc.selectNodes("//payment")
Then I iterate through each payment node and then querying the allocations node (assuming only one) and the allocation nodes (assuming more than one). Each allocation node is removed from its parent and added to the allocations node. The same is then done with the payment.
dim p
for p = 0 to paymentNodes.length - 1
dim payment: set payment = paymentNodes.Item(p)
dim allocationsNode: set allocationsNode = payment.selectSingleNode("./allocations")
dim allocationNodes: set allocationNodes = payment.selectNodes("./allocation")
dim a
for a = 0 to allocationNodes.length - 1
dim allocation: set allocation = allocationNodes.Item(a)
allocation.parentNode.removeChild allocation
allocationsNode.appendChild allocation
next
payment.parentNode.removeChild payment
paymentsNode.appendChild payment
next
Because the payments node is now a valid root node, I reload the XML at the payment level into the xmldoc object to remove our temporary root node before saving to disk.
xmldoc.loadXML xmldoc.selectSingleNode("/root/payments").xml
xmldoc.save "output.xml"
An alternative to direct node manipulation would be to use an XSL Transform but again, you'd need to correct for the root node. This may be a better choice if your input XML file is large.
<payments/><payment/>to<payments><payment/> ... </payments>?