Kelly
Kelly

Reputation: 295

Simple way to group XML elements in PowerShell by attribute

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

Answers (1)

Keith Hill
Keith Hill

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

Related Questions