Reputation: 295
I have a simple XML document I'm parsing in PowerShell and need to group elements by attribute value. Here's what the XML looks like in structure:
<Root>
<Items>
<Item Input="Foo1" Output="Bin/A" />
<Item Input="Foo2" Output="Bin/A" />
<Item Input="Foo3" Output="Bin/B" />
<Item Input="Foo4" Output="Bin/C" />
<Item Input="Foo5" Output="Bin/A" />
</Items>
</Root>
For reasons not worth discussing I cannot reformat the XML so suggestions such as making an Output tag and putting Items as children are not valid.
What I want to end up with is essentially a dictionary that maps each unique Output string to a list of nodes that have that string for their Output attribute.
I can do this manually by iterating the elements, creating dictionaries as I see new Output values, and filling in the lists in a big loop, but I was curious: is there was a more elegant way with PowerShell query syntax or XPath magic to create this dictionary? I've been using PowerShell query syntax recently and find it has a lot of capabilities; is this task within that scope?
Upvotes: 1
Views: 2492
Reputation: 201822
Something like this should work for you:
$xml = [xml] @'
<Root>
<Items>
<Item Input="Foo1" Output="Bin/A" />
<Item Input="Foo2" Output="Bin/A" />
<Item Input="Foo3" Output="Bin/B" />
<Item Input="Foo4" Output="Bin/C" />
<Item Input="Foo5" Output="Bin/A" />
</Items>
</Root>
'@
$grouped = $xml.Root.Items.Item | Group Output
$grouped
Gives:
Count Name Group
----- ---- -----
3 Bin/A {Item, Item, Item}
1 Bin/B {Item}
1 Bin/C {Item}
Upvotes: 3