简体   繁体   中英

Powershell: saving xml changes in a new xml variable or object, keeping the original object unchanged

I have a xml variable that I get from Invoke-restmethod . Lets call it $object1

I want to make a new variable or object $object2 that is the same as $object1 but with a few changes to the values

Here is what I have tried:

$object2 = $object1

$object2.sweets.candy.Where({$_.lemondrop -gt 1}) | Foreach{$_.gumdrop = 20}

Now the problem with that is when I double check $object1 the value is changed there too... I dont want that

I just want the chage to remain in $object2

What am I doing wrong here?

You need to clone $object1 in order to obtain an independent copy of it:

$object2 = $object1.Clone() # assumes that $object's type implements ICloneable

[System.Xml.XmlDocument] is a reference type (as opposed to a value type such as [int] ), which means that:

$object2 = $object1

simply makes $object2 reference (point to) the very same object as $object1 .

You can verify this as follows:

[object]::ReferenceEquals($object1, $object2)

Generally:

  • = with a value type instance creates a copy of the actual value , ie, it implicitly clones.

  • = with a reference type instance creates a copy of the reference to the instance, ie, it creates another reference to the very same object.

  • The same applies when you add elements to a (mutable) collection ; eg (assume having created a list with $list = [System.Collections.Generic.List[object]] @() ):

    • $var = 42; $list.Add($var) $var = 42; $list.Add($var) adds a copy of the value-type ( [int] ) instance to the list.
    • $var = [pscustomobject] @{ foo = 'bar' }; $list.Add($var) $var = [pscustomobject] @{ foo = 'bar' }; $list.Add($var) adds a reference to the reference-type ( [pscustomobject] ) instance to the list.

To determine if a given type is a value type or a reference type , use the type's Boolean .IsValueType property:

# Inspect a type directly.
PS> [System.Xml.XmlDocument].IsValueType
False    # -> a *reference* type

# Inspect a type via an instance thereof:
PS> $xml = [xml] '<xml/>'; $xml.GetType().IsValueType
False 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM