我有一个xml文件,如下所示。
<Packages>
<package name="testR0" testversion="1.0.0.0" type="A">
<package name="testR1" testversion="1.0.0.1" type="A">
</package>
<package name="testR2" testversion="1.1.0.0" type="A">
<package name="testR3" testversion="1.1.1.0" type="B">
<package name="testR4" testversion="1.1.1.1" type="C">
</package>
<package name="testR5" testversion="1.1.1.2" inc="true" type="C">
</package>
<package name="testR6" testversion="1.1.1.3" inc="true" type="C">
</package>
</package>
</package>
</package>
</Packages>需要将两个给定包名的测试版本和类型添加到字典中。如果我传递TestR0和TestR3,那么它应该添加来自TestR2、TestR3以及TestR5和TestR6的测试版本和类型,其中inc=true。因此,生成的字典应该如下所示
{[1.1.0.0, A],[1.1.1.0, B],[1.1.1.2, C],[1.1.1.3, C]}但是,即使我得到了值,字典也没有正确填充。它就像下面给出的那样。只有[1.1.0.0, A]出现在字典中
{[1.1.0.0, A]},[1.1.1.0, B],[1.1.1.2, C],[1.1.1.3, C]我的代码如下所示
function Get-Listver {
PROCESS {
[xml] $versionInfo = Get-Content -Raw -Path "C:\test\test.xml"
$firstXML = Select-Xml -Xml $versionInfo -XPath "//*[@name='testR0']"
$secondXML = Select-Xml -Xml $versionInfo -XPath "//*[@name='testR3']"
$packagecollection = Get-AllPackageVersion $secondXML.Node $firstXML.Node
return $packagecollection
}
}
function Get-AllPackageVersion {
[CmdletBinding()]
param (
$secondXML,
$firstXML
)
process {
$packagecollection = New-Object System.Collections.Generic.Dictionary"[String,String]"
if($secondXML.type -eq 'B'){
$preReq = $secondXML.ChildNodes | Where-Object {$_.inc -eq "true"}
if($preReq)
{
foreach($pq in $preReq)
{
$testver = $pq.testversion
$testtyp = $pq.type
$packagecollection.Add("$testver", "$testtyp")
}
}
}
$testver = $secondXML.testversion
$testtyp = $secondXML.type
$packagecollection.Add("$testver", "$testtyp")
if($secondXML.ParentNode.Name -ne $firstXML.ParentNode.Name -and $secondXML.ParentNode.Name -ne $firstXML.Name){
Get-AllPackageVersion $secondXML.ParentNode $firstXML
}
if ($packagecollection.count -gt 1)
{
$packagecollection = $packagecollection.GetEnumerator() | sort -Property key
}
return $packagecollection;
}
}
Get-Listver结果:

发布于 2020-08-15 05:16:49
尝试对脚本进行以下修改:
function Get-AllPackageVersion {
[CmdletBinding()]
param (
$secondXML,
$firstXML
)
process {
if($secondXML.type -eq 'B'){
$preReq = $secondXML.ChildNodes | Where-Object {'inc' -in $_.psobject.Properties.Name -and $_.inc -eq "true"}
if($preReq) {
foreach($pq in $preReq) {
$testver = $pq.testversion
$testtyp = $pq.type
$packagecollection.Add("$testver", "$testtyp")
}
}
}
$testver = $secondXML.testversion
$testtyp = $secondXML.type
$packagecollection.Add("$testver", "$testtyp")
if($secondXML.ParentNode.Name -ne $firstXML.ParentNode.Name -and
$secondXML.ParentNode.Name -ne $firstXML.Name){
Get-AllPackageVersion $secondXML.ParentNode $firstXML
}
}
}
function Get-Listver {
PROCESS {
[xml] $versionInfo = Get-Content -Raw -Path "C:\test\test.xml"
$firstXML = Select-Xml -Xml $versionInfo -XPath "//*[@name='testR0']"
$secondXML = Select-Xml -Xml $versionInfo -XPath "//*[@name='testR3']"
$packagecollection = New-Object System.Collections.Generic.Dictionary"[String,String]"
Get-AllPackageVersion $($secondXML.Node) $($firstXML.Node)
return $packagecollection
}
}
Get-Listver输出(没有理由对Dictionary类型的对象进行“可视”排序):
$x = .\SO\63401378.ps1; $x; $x.Count, $x.GetType().Name
Key Value
--- -----
1.1.1.2 C
1.1.1.3 C
1.1.1.0 B
1.1.0.0 A
4
Dictionary`2发布于 2020-08-15 05:27:05
扩展@JosefZ的注释,你从你的函数中输出了4个项目,但是你得到了一些混合的类型:

问题在于,这取决于您是否访问此代码路径:
if ($packagecollection.count -gt 1)
{
$packagecollection = $packagecollection.GetEnumerator() | sort -Property key
}在函数的末尾返回一个Dictionary或System.Object[]数组。
在您的特定示例中,输出中的第一项(testR2)没有命中代码路径,因此您得到一个包含一项的字典,但是testR3命中该代码路径并输出一个包含3项(testR3、testR5和testR6)的System.Object[]数组,该数组被展开并附加到输出中。
解决方案是确保返回一致的类型,而不管字典中有多少项。要做到这一点,一种方法是始终对字典进行排序,以便将其强制放入一个数组中,而不管其中有多少个条目。
更改上面的代码片段以删除if
$packagecollection = $packagecollection.GetEnumerator() | sort -Property key现在你得到了:

顺便说一句,您的代码在复查时有点混乱,因为您混合了对Get-AllPackageVersion $secondXML.ParentNode $firstXML的递归调用的隐式输出和通过return $packagecollection;的cmdlet输出,并且您的隐式输出是在构建$packagecollection的过程中生成的。如果您将if($secondXML.ParentNode.Name ...块移到函数的顶部,以便更清楚地表明它首先被写入到输出管道中,则可能更容易阅读。
https://stackoverflow.com/questions/63401378
复制相似问题