我正在开发一个名为Merge-Xsd
的cmdlet,它可以合并类似的XML模式。它采用路径列表,加载模式,合并它们,并生成XMLDocument
作为输出。
特定文件名的所有模式都被视为"类似",所以我正在做的是获取特定目录结构中的所有子项,根据文件名对它们进行分组,然后尝试将它们传递给我的自定义cmdlet。
将它们分组很简单:
$grouping = Get-ChildItem -Recurse -Filter *.xsd |
Group-Object -Property Name -AsHashTable -AsString
但是,将它们作为同一管道的一部分进行处理却不是。我已经接近这个了:
$grouping.Keys |
ForEach-Object { ($grouping[$_] |
Select-Object -ExpandProperty FullName | Merge-Xsd).Save("C:\Out\$_") }
但我真正希望能够做到的是ForEach-Object
之后直接使用Group-Object
来迭代每个组项,从而无需单独的$grouping
变量。
如何使用ForEach-Object
获取键/值对,同时保持Merge-Xsd
每次调用该特定键/值对的范围?
20150224更新:
Merge-Xsd
选项集非常基本:
NAME
Merge-Xsd
SYNTAX
Merge-Xsd [-Path] <string[]> [<CommonParameters>]
它实际上只是用于一次性抛出一堆文件并将它们合并为单个输出,即XmlDocument
。 (我将输出建模为ConvertTo-Xml
。)
答案 0 :(得分:6)
我认为你可以像这样嵌套:
Get-ChildItem -Recurse -Filter *.xsd |
Group-Object -Property Name |
ForEach-Object {
($_.Group.FullName | Merge-Xsd).Save("C:\Out\$($_.Name)")
}
我没有您的cmdlet或文件,但在我的有限测试中,这将有效。
我取出了-AsHash
和-AsString
参数,因此我们可以直接处理Group-Object
返回的群组对象。
$_.Group.FullName
比初看起来更复杂。 $_
这里指的是单个群组对象,因为我们在ForEach-Object
中。 group对象包含一个名为Name
的属性,它是组的名称,以及一个名为Group
的属性,它实际上是组中各个项的集合,因此$_.Group
是一个集合。
从这里开始,将 再次传递给ForEach-Object
是有意义的,因为该集合中的每个项目都是FileInfo对象,并且您希望得到{{ 1}}传递给FullName
的属性。
这里我们利用一些powershell魔法。当您引用Merge-Xsd
其中$c.Property
是具有$c
属性的对象集合时,您将获得一个由属性对象组成的集合。
所以Property
与:
$props = $c.Property
知道这一点,我们可以将$props = $c | ForEach-Object { $_.Property }
直接传送到$_.Group.FullName
,以传递组中所有文件的所有完整名。
在该上下文中,Merge-Xsd
仍然引用组对象,因此它是组的名称,而不是文件的名称。