0

I need to merge two XML files in Excel VBA. 2nd XML file should be added as a sibling of 1st XML. Also have to create a Union after merging the XML files. For example:

1st XML file:

<TupleList>
    <Member FullPath="Latest : FOLDER Day Ending 06-16-2019"/>
</TupleList>

2nd XML file:

 <TupleList>
   <Member FullPath="Latest : FOLDER Day Ending 06-17-2019"/>
 </TupleList>

Expected Output XML file:

 <Union>
  <TupleList>
    <Member FullPath="Latest : FOLDER Day Ending 06-16-2019"/>
  </TupleList>
  <TupleList>
   <Member FullPath="Latest : FOLDER Day Ending 06-17-2019"/>
  </TupleList>
 </Union>

I tried below code but its not working as expected

  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

It provides output with Tuplelist as parent and 2 Members as Child. But I want output in above-expected format.

2
  • 2
    Valid XML has a single root element - this seems to be a problem for your expected output. Commented Jul 22, 2019 at 0:13
  • Got it. Then I can create a tag Union before the tuplelist. Updated the expected output Commented Jul 22, 2019 at 0:18

2 Answers 2

2

If you have lots of files you could put them in a folder then use cmd to combine them into one file (assuming they don't have root nodes). Then use fileSystemObject to add the root node. I decided to work with the existing document though I thought about using .appendChild and .createElement to add the root node with an additional document variable. Think I might actually prefer that.

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

References:

  1. https://www.tek-tips.com/viewthread.cfm?qid=1421842
  2. https://en.wikipedia.org/wiki/Substitute_character
  3. Combining multiple xml documents into one large one with a batch file @Bhaskar
  4. Create xml rootNode via c#
Sign up to request clarification or add additional context in comments.

6 Comments

@YasserKhalil try adding a short delay before.
you have any blank lines at bottom of files? Or empty files? learn.microsoft.com/en-us/office/vba/language/reference/…
So two files with the different xml in each? And in the right folder?
Nope. Try stepping through with F8
Thanks a lot. Now solved and I tried several times. ` Application.Wait Now + TimeValue("00:00:03") AddRootNode COMBINED_FILE_PATH, fso `
|
2

This worked for me:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.