114
114

Reputation: 926

Appending a Child to a Node Elsewhere in an XML Document

The following VBA code takes an XML file and appends a specific node to other nodes within the document:

Dim xmlFilePath$, newFilePath$
Dim DOM As MSXML2.DOMDocument
Dim Node As IXMLDOMNode
Dim fso As Scripting.FileSystemObject
Dim itm As IXMLDOMNode

xmlfilepath = "Path"

newfilepath = "Path_2"

Set DOM = CreateObject("MSXML2.DOMDocument.6.0")

DOM.Load xmlFilePath

For Each Node In DOM.DocumentElement.getElementsByTagName("Tag")
   For Each itm In Node.ParentNode.NextSibling.ChildNodes
            itm.appendChild Node.CloneNode(True)
    Next
Next

Set fso = CreateObject("Scripting.FileSystemObject")

Set DOM = Nothing
Set fso = Nothing
Set Node = Nothing

End Sub

This code works perfectly fine as written. However, if the loop

For Each Node In DOM.DocumentElement.getElementsByTagName("Tag")
   For Each itm In Node.ParentNode.NextSibling.ChildNodes
            itm.appendChild Node.CloneNode(True)
    Next
Next

is changed to

For Each Node In DOM.DocumentElement.getElementsByTagName("Tag")
   For Each itm In Node.ParentNode.ParentNode
            itm.appendChild Node.CloneNode(True)
    Next
Next

I get an 'object required' error. If I instead use Node.ParentNode.ParentNode.ChildNodes I get no error, but the node I am trying to append gets placed inside an already existing child node so that the result is something like <a>Example<b>More_Writing</b></a>.

Is there a way to have the path Node.ParentNode.ParentNode accepted as valid, or should I be approaching this a different way?

Upvotes: 1

Views: 5622

Answers (2)

ErdiHaensel
ErdiHaensel

Reputation: 31

As Tim Williams provided the code which works fine. To resolve the problem with your XML not updating, you need to save your XML just like you have opened the XML

'Open XML
DOM.Load xmlFilePath

'Edit XML
For Each Node In DOM.DocumentElement.getElementsByTagName("Tag")
    Node.ParentNode.ParentNode.appendChild Node.CloneNode(True)
Next

'Save XML
Dom.Save xmlFilePath

Upvotes: 0

Tim Williams
Tim Williams

Reputation: 166316

Node.ParentNode.ParentNode will return a single node, not a collection, so you don't need the inner For Each loop :

For Each Node In DOM.DocumentElement.getElementsByTagName("Tag")
   Node.ParentNode.ParentNode.appendChild Node.CloneNode(True)
Next

Upvotes: 1

Related Questions