Мне нужно объединить два файла XML в Excel VBA. 2-й XML-файл должен быть добавлен как родственный 1-му XML-файлу. Также необходимо создать Union после объединения файлов XML. Например:
1-й XML-файл:
<TupleList>
<Member FullPath = "Latest : FOLDER Day Ending 06-16-2019"/>
</TupleList>
2-й XML-файл:
<TupleList>
<Member FullPath = "Latest : FOLDER Day Ending 06-17-2019"/>
</TupleList>
Ожидаемый выходной XML-файл:
<Union>
<TupleList>
<Member FullPath = "Latest : FOLDER Day Ending 06-16-2019"/>
</TupleList>
<TupleList>
<Member FullPath = "Latest : FOLDER Day Ending 06-17-2019"/>
</TupleList>
</Union>
Я пробовал код ниже, но он не работает должным образом
Set XOuter = CreateObject("MSXML2.DOMDocument")
Set XOuter1 = CreateObject("MSXML2.DOMDocument")
Dim appendNode As MSXML2.IXMLDOMNode
XOuter.Load ("C:\\blp\\1stXML.xml")
XOuter1.Load ("C:\\blp\\2ndXML.xml")
For Each appendNode In XOuter1.DocumentElement.ChildNodes
XOuter.DocumentElement.appendChild appendNode
Next
Он обеспечивает вывод с Tuplelist в качестве родителя и 2 Members в качестве дочернего элемента. Но я хочу вывести в ожидаемом выше формате.
Понятно. Затем я могу создать тег Union перед списком кортежей. Обновлен ожидаемый результат


Это сработало для меня:
Dim inDoc As New MSXML2.DOMDocument60
Dim resultDoc As New MSXML2.DOMDocument60
Dim rt As Object, nd
Set rt = resultDoc.appendChild(resultDoc.createElement("Union"))
Debug.Print resultDoc.XML
''using loadXML here for convenience...
inDoc.LoadXML ("<TupleList><Member FullPath = ""Latest : FOLDER Day Ending 06-16-2019""/></TupleList>")
Set nd = resultDoc.importNode(inDoc.DocumentElement, True)
rt.appendChild nd
inDoc.LoadXML ("<TupleList><Member FullPath = ""Latest : FOLDER Day Ending 06-17-2019""/></TupleList>")
Set nd = resultDoc.importNode(inDoc.DocumentElement, True)
rt.appendChild nd
Debug.Print resultDoc.XML
Если у вас много файлов, вы можете поместить их в папку, а затем использовать cmd, чтобы объединить их в один файл (при условии, что у них нет корневых узлов). Затем используйте fileSystemObject, чтобы добавить корневой узел. Я решил работать с существующим документом, хотя думал об использовании .appendChild и .createElement для добавления корневого узла с дополнительной переменной документа. Думаю, я мог бы на самом деле предпочесть это.
Option Explicit
Public Sub CombineFiles()
Dim cmd As String, fso As Object, xmlDoc As Object, numberOfFilesInFolder As Long, folder As Object
Const FOLDER_PATH As String = "C:\Users\User\Desktop\XML Test"
Const COMBINED_FILE_PATH As String = "C:\Users\User\Desktop\XML Test\Combined.xml"
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(FOLDER_PATH)
numberOfFilesInFolder = folder.Files.Count
cmd = "cmd /c cd """ & folder & """ && copy *.xml Combined.xml"
Shell cmd, vbNormalFocus
Do
DoEvents
Loop Until folder.Files.Count = numberOfFilesInFolder + 1
AddRootNode COMBINED_FILE_PATH, fso
Set xmlDoc = CreateObject("MSXML2.DOMDocument")
With xmlDoc
.validateOnParse = True
.setProperty "SelectionLanguage", "XPath"
.async = False
If Not .Load(COMBINED_FILE_PATH) Then
Err.Raise .parseError.ErrorCode, , .parseError.reason
Exit Sub
End If
End With
End Sub
Public Sub AddRootNode(ByVal filepath As String, fso As Object)
Const READING = 1
Const WRITING = 2
Dim file As Object, contents As String
Set file = fso.OpenTextFile(filepath, READING)
contents = file.ReadAll
file.Close
contents = "<Union>" & vbCrLf & Replace$(contents, Chr$(26), vbNullString) & vbCrLf & "</Union>"
Set file = fso.OpenTextFile(filepath, WRITING, True)
file.Write contents
file.Close
End Sub
Использованная литература:
@YasserKhalil попробуйте добавить короткую задержку раньше.
у вас есть пустые строки внизу файлов? Или пустые файлы? docs.microsoft.com/en-us/office/vba/language/reference/…
Итак, два файла с разными xml в каждом? И в нужную папку?
Неа. Попробуйте пройти через F8
Итак, вопрос времени. Вы поставили паузу перед добавлением корневого узла?
Большое спасибо. Теперь решено, и я пытался несколько раз. `Application.Wait Now + TimeValue("00:00:03") AddRootNode COMBINED_FILE_PATH, fso `
Действительный XML имеет один корневой элемент - это кажется проблемой для ожидаемого результата.