Powershell: Unable to use multiple XmlElement objects?

Created on 14 Sep 2019  路  2Comments  路  Source: PowerShell/PowerShell

Let's say I want to pull some XML from a website:

PS C:\WINDOWS\system32> $content = Invoke-RestMethod -Uri https://www.bankofcanada.ca/valet/observations/FXCADUSD/xml -Method Get

And let's say I want to peel off some of the subelements and fool around with them, like I would with any other object:

PS C:\WINDOWS\system32> $test = $content.data.seriesDetail.series
PS C:\WINDOWS\system32> $test

id       label   description                                      dimension
--       -----   -----------                                      ---------
FXCADUSD CAD/USD Canadian dollar to US dollar daily exchange rate dimension

PS C:\WINDOWS\system32> $test.id = "12345678"
PS C:\WINDOWS\system32> $test

id       label   description                                      dimension
--       -----   -----------                                      ---------
12345678 CAD/USD Canadian dollar to US dollar daily exchange rate dimension

Why is it that the parent document ends up being affected?

PS C:\WINDOWS\system32> $content.data.seriesDetail.series

id       label   description                                      dimension
--       -----   -----------                                      ---------
12345678 CAD/USD Canadian dollar to US dollar daily exchange rate dimension

PS C:\WINDOWS\system32>

Is this intended behavior?

Issue-Question Resolution-Answered

Most helpful comment

Not so much explicitly _intended_ by PowerShell, but more a function of how reference types behave.

A majority of .NET types are reference types, which means that if you assign the value to another variable, only the reference to that item is assigned. This avoids what would otherwise be a significant amount of processing overhead that would be required to entirely copy the objects, and essentially means that if you assign a reference to a variable, it will still affect the original variable or the original object it was attached to.

To cover the few cases where you _do_ want to create actual copies of items, many classes have Clone() methods which can be applied to create copies, though the degree to which they are copied and how much data can be duplicated will vary depending on the implementation for that individual class.

According to the documentation here there is a .CloneNode() method on XmlElement, so you should be able to do $test = $content.data.seriesDetail.series.CloneNode($true) to create a copy of the node to work with and modify without affecting the original node. The $true boolean tells the method to copy all child nodes as well; if you instead pass $false as the argument, only the target node is cloned; all child nodes would remain references to the originals.

All 2 comments

Not so much explicitly _intended_ by PowerShell, but more a function of how reference types behave.

A majority of .NET types are reference types, which means that if you assign the value to another variable, only the reference to that item is assigned. This avoids what would otherwise be a significant amount of processing overhead that would be required to entirely copy the objects, and essentially means that if you assign a reference to a variable, it will still affect the original variable or the original object it was attached to.

To cover the few cases where you _do_ want to create actual copies of items, many classes have Clone() methods which can be applied to create copies, though the degree to which they are copied and how much data can be duplicated will vary depending on the implementation for that individual class.

According to the documentation here there is a .CloneNode() method on XmlElement, so you should be able to do $test = $content.data.seriesDetail.series.CloneNode($true) to create a copy of the node to work with and modify without affecting the original node. The $true boolean tells the method to copy all child nodes as well; if you instead pass $false as the argument, only the target node is cloned; all child nodes would remain references to the originals.

This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

be5invis picture be5invis  路  170Comments

SteveL-MSFT picture SteveL-MSFT  路  189Comments

dragonwolf83 picture dragonwolf83  路  127Comments

NJ-Dude picture NJ-Dude  路  64Comments

andschwa picture andschwa  路  64Comments