I'm developing a cmdlet called Merge-Xsd
that can merge similar XML schemas. It takes a list of paths, loads the schemas, merges them, and produces an XMLDocument
as output.
All schemas of a particular file name are considered "similar", and so what I'm doing is getting all of the child items in a particular directory structure, grouping them according to the file name, and then trying to pass them to my custom cmdlet.
Grouping them is easy:
$grouping = Get-ChildItem -Recurse -Filter *.xsd |
Group-Object -Property Name -AsHashTable -AsString
However, processing them as part of the same pipeline is not. I've gotten as close as this:
$grouping.Keys |
ForEach-Object { ($grouping[$_] |
Select-Object -ExpandProperty FullName | Merge-Xsd).Save("C:\Out\$_") }
But what I'd really like to be able to do is use ForEach-Object
directly after Group-Object
to iterate over each group item, thus eliminating the need for the separate $grouping
variable.
How can I use ForEach-Object
to get the key/value pair while keeping each invocation of Merge-Xsd
scoped to that particular key/value pair?
20150224 UPDATE:
The Merge-Xsd
option set is extremely basic:
NAME
Merge-Xsd
SYNTAX
Merge-Xsd [-Path] <string[]> [<CommonParameters>]
It is really just intended for throwing a bunch of files at it in one go and having them merged into a single output, which is an XmlDocument
. (I modeled the output off of ConvertTo-Xml
.)
I think you could just nest it like this:
Get-ChildItem -Recurse -Filter *.xsd |
Group-Object -Property Name |
ForEach-Object {
($_.Group.FullName | Merge-Xsd).Save("C:\Out\$($_.Name)")
}
I don't have your cmdlet or files but in my limited testing this would work.
I took out the -AsHash
and -AsString
parameters so we could deal directly with the group objects returned by Group-Object
.
The $_.Group.FullName
is more complex than it seems on first glance. $_
here refers to a single group object, since we're in a ForEach-Object
. The group object contains a property called Name
which is the name of the group, and a property called Group
which is actually a collection of the the individual items within the group, so $_.Group
is a collection.
From here, it would make sense to pipe that to ForEach-Object
again, since each of the items in that collection will be a FileInfo object, and you want to get the FullName
property to pass to Merge-Xsd
.
Here we take advantage of some powershell magic. When you refer to $c.Property
where $c
is a collection of objects with a Property
property, you get back a collection that consists of the property objects.
So $props = $c.Property
is the same as:
$props = $c | ForEach-Object { $_.Property }
Knowing that, we can pipe $_.Group.FullName
directly into Merge-Xsd
to pass along all of the fullnames from all of the files in the group .
In that context, $_.Name
still refers to the group object, so it's the name of the group, not the name of the file.
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.