Мое окончательное решение: адаптировал XMLWriter, упомянутый divo (использовал его почти как есть, за исключением одного или двух изменений, так как этот скрипт должен запускаться на клиенте). Также адаптировал код из здесь для красивой печати XML (чтобы его можно было прочитать при выводе в файл):
Function XMLToString(Nodes)
dim retStr
retStr = "<?xml version=""1.0"" encoding=""utf-8"" ?>"
XMLToString = retStr & vbNewLine & NodesToString(Nodes, 0)
End Function
Function NodesToString(Nodes, Indent)
Dim xNode
Dim retStr
retStr = ""
For Each xNode In Nodes
Select Case xNode.nodeType
Case 1: ' NODE_ELEMENT
If xNode.nodeName <> "#document" Then
' change DisplayAttrs_(xNode, Indent + 2) to
' DisplayAttrs_(xNode, 0) for inline attributes
retStr = retStr & VBNewLine & strDup(" ", Indent) & "<" & xNode.nodeName & AttributesToString(xNode) & ">"
If xNode.hasChildNodes Then
retStr = retStr & NodesToString(xNode.childNodes, Indent + 2)
End If
retStr = retStr & VBNewLine & strDup(" ", Indent) & "</" & xNode.nodeName & ">"
Else
If xNode.hasChildNodes Then
retStr = retStr & NodesToString(xNode.childNodes, Indent + 2)
End If
End If
Case 3: ' NODE_TEXT
retStr = retStr & VBNewLine & strDup(" ", Indent) & xNode.nodeValue
End Select
Next
NodesToString = retStr
End Function
Function AttributesToString(Node)
Dim xAttr, res
res = ""
For Each xAttr In Node.attributes
res = res & " " & xAttr.name & "=""" & xAttr.value & """"
Next
AttributesToString = res
End Function
Function strDup(dup, c)
Dim res, i
res = ""
For i = 1 To c
res = res & dup
Next
strDup = res
End Function