Adeq Hero
Adeq Hero

Reputation: 137

Remove Nodes with duplicate XML elements in Powershell

I Have an xml that looks like this:

myobjects>
<allobjects>
<object name="firstObject" username="usr" pass="pass" specialLine="E:\folder1\files for home  /c /x /waitsecs 30 " default="Yes" binary="1"/>
<object name="secondObjec" username="usr1" pass="thispass" specialLine="E:\folder1\files for home  /c /x /waitsecs 30 " default="no" binary="1" />
<object name="thirdObject" username="usr2" pass="pass1" specialLine="E:\folder1\files for home  /c /x /waitsecs 40 " default="Yes" binary ="0" />
<object name="fourthObject" username="usr3" pass="pass3" specialLine="D:\folder1\files for office  /c /x /waitsecs 50 " default="Yes"  binary="1"/>
<object name="firstobject 1" username="usr4" pass="pass5" specialLine="E:\folder1\files for home  /c /x /waitsecs 30 " default="Yes" binary="0"/>
</allobjects>
<myobjects

I want to delete every element with the value "binary="0" which I could easily accomplish using the where-Object as below:

[xml]$myfile = [xml](Get-content path_to_my_file)
 $myfile.myobjects.allobjects.childNodes | where-object{$_.binary -eq 0} |foreach-Object{ do my deletion function}

What I want do do next is delete every Node where the specialLine value is the same (remain with only one Node for every exactly same specialLines). I could get unique specialLines using this $myfile.myobjects.allobjects.object.special | sort-object | get-Unique

and I just can't find a way to delete nodes and remain with nodes with unique specialLines. I've tried something like this:

$myfile.myobjects.allobjects.childNodes | where-object{$myfile.myobjects.allobjects.object.special | sort-object | get-Unique`} |foreach-Object{ do my deletion function}

but I think i'm missing something or my approach to this is entirely wrong. Any suggestions or help will be appreciated.

Upvotes: 0

Views: 605

Answers (1)

AdminOfThings
AdminOfThings

Reputation: 25001

You could use a combination of Group-Object on the specialLine property and Select-Object's -Skip parameter to select the nodes to remove.

$nodesToRemove = $myfile.myobjects.allobjects.childnodes | Group-Object specialLine |
    Foreach-Object { $_.Group | Select-Object -Skip 1 }

$nodesToRemove | Foreach-Object {
    $myfile.myobjects.allobjects.RemoveChild($_)
}

The idea is to skip the first object in each group (specialLine value). If a group is unique, then the entire group will be skipped.

Upvotes: 1

Related Questions