如何迭代使用PSCustomObject
转换为ConvertFrom-JSON
的JSON数组?使用foreach
不起作用。
$jsonArray ='[{"privateKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\key.pem"},
{"publicKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\cert.pem"},
{"publicKeyCALocation" : "C:\\ProgramData\\docker\\certs.d\\ca.pem"}]'
$json = convertfrom-json $jsonArray
$json | foreach {$_}
返回
privateKeyLocation
------------------
C:\ProgramData\docker\certs.d\key.pem
枚举器虽然说有3个数组成员
>$json.Count
3
答案 0 :(得分:2)
您遇到的问题并非特定于它是一个JSON数组,它与默认情况下显示数组中自定义对象的方式有关。最简单的答案是将其传递给Format-List
(或简称为FL
)。
PS C:\Users\TMTech> $JSON|FL
privateKeyLocation : C:\ProgramData\docker\certs.d\key.pem
publicKeyLocation : C:\ProgramData\docker\certs.d\cert.pem
publicKeyCALocation : C:\ProgramData\docker\certs.d\ca.pem
除此之外,当PowerShell输出一个对象数组时,它将显示的列基于数组中第一个对象的属性。在您的情况下,该对象具有一个名为“privateKeyLocation”的属性,因此这是唯一出现的列,并且由于其他两个对象没有该属性,因此它不会显示任何内容。如果你想把它保存为一个表,你可以收集所有潜在的属性,并将它们添加到具有空值的第一个项目,这将允许你将它显示为一个表,但它仍然看起来不太好:< / p>
$json|%{$_.psobject.properties.name}|select -Unique|?{$_ -notin $json[0].psobject.Properties.Name}|%{Add-Member -InputObject $JSON[0] -NotePropertyName $_ -NotePropertyValue $null}
然后你可以输出一个表并获得所有东西:
PS C:\Users\TMTech> $json
privateKeyLocation publicKeyLocation publicKeyCALocation
------------------ ----------------- -------------------
C:\ProgramData\docker\certs.d\key.pem
C:\ProgramData\docker\certs.d\cert.pem
C:\ProgramData\docker\certs.d\ca.pem
编辑:在这种情况下获取每个对象的值很棘手,因为要扩展的属性会不断更改每个对象。有两种方法可以做到这一点,我能想到的是,我认为正确的方式,然后是简单的方法。正确的方法是确定要扩展的属性,然后直接引用该属性:
$JSON |%{
$PropName = $_.PSObject.Properties.Name
$_.$PropName
}
那会做你想要的,但我认为更容易管道到Format-List
,然后Out-String
,将整个事物包裹在括号中,拆分新行并将所有内容替换为{ {1}}应该只留下你想要的路径。
:
答案 1 :(得分:1)
足够有趣。我在另一个论坛上从同一个OP回复了这个确切的问题。虽然我的回答只是RegEx并且已完成,但没有额外的转换。
Of course there are several ways to do this. The below is just what I came up with.
$jsonArray = '[{"privateKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\key.pem"},
{"publicKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\cert.pem"},
{"publicKeyCALocation" : "C:\\ProgramData\\docker\\certs.d\\ca.pem"}]'
([regex]::Matches($jsonArray,'(?<=\").:\\[^\"]+(?=\")').Value) -replace '\\\\','\' `
| ForEach {
If (Test-Path -Path $_)
{"path $_ found"}
Else {Write-Warning "Path $_ not found"}
}
WARNING: Path C:\ProgramData\docker\certs.d\key.pem not found
WARNING: Path C:\ProgramData\docker\certs.d\cert.pem not found
WARNING: Path C:\ProgramData\docker\certs.d\ca.pem not found
所以,也许不像这里发布的那样优雅,但它会让OP成为他们想要的地方。
因此,巩固TheMadTechnician提供的所有内容以及OP所追求的内容,并尽量使其尽可能简洁,将给OP提供以下内容(我添加了一个元素以显示正面响应):
Clear-Host
($jsonArray = @'
[{"privateKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\key.pem"},
{"publicKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\cert.pem"},
{"publicKeyCALocation" : "C:\\ProgramData\\docker\\certs.d\\ca.pem"},
{"publicKeyTestFileLocation" : "D:\\Temp\\test.txt"}]
'@ | ConvertFrom-Json | Format-List | Out-String) -split '[\r\n]+' -replace '(?m)^.+ : '`
| Where-Object {$_} | ForEach {
If(Test-Path -Path $_){"The path $_ was found"}
Else{Write-Warning -Message "The path $_ was not found}"}
}
WARNING: The path C:\ProgramData\docker\certs.d\key.pem was not found}
WARNING: The path C:\ProgramData\docker\certs.d\cert.pem was not found}
WARNING: The path C:\ProgramData\docker\certs.d\ca.pem was not found}
The path D:\Temp\test.txt was found
哪一个更符合他的喜好,当然是选择OP的问题。
两次测试之间的性能各不相同,但使用直接RegEx方法的最快时间是:
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 43
Ticks : 439652
TotalDays : 5.08856481481481E-07
TotalHours : 1.22125555555556E-05
TotalMinutes : 0.000732753333333333
TotalSeconds : 0.0439652
TotalMilliseconds : 43.9652
并且合并版本中最快的是:
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 54
Ticks : 547810
TotalDays : 6.34039351851852E-07
TotalHours : 1.52169444444444E-05
TotalMinutes : 0.000913016666666667
TotalSeconds : 0.054781
TotalMilliseconds : 54.781
更新以添加iRon对此主题的看法
所以这......
$jsonArray ='[{"privateKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\key.pem"},
{"publicKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\cert.pem"},
{"publicKeyCALocation" : "C:\\ProgramData\\docker\\certs.d\\ca.pem"}]'
$json = convertfrom-json $jsonArray
$json | ForEach {
$Key = $_.psobject.properties.name;
"Testing for key " + $_.$Key
Test-Path -Path $_.$Key
}
Testing for key C:\ProgramData\docker\certs.d\key.pem
False
Testing for key C:\ProgramData\docker\certs.d\cert.pem
False
Testing for key C:\ProgramData\docker\certs.d\ca.pem
False
......而且这个:
('[{"privateKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\key.pem"},
{"publicKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\cert.pem"},
{"publicKeyCALocation" : "C:\\ProgramData\\docker\\certs.d\\ca.pem"}]' `
| convertfrom-json) | ForEach {
$Key = $_.psobject.properties.name;
"Testing for key " + $_.$Key
Test-Path -Path $_.$Key
}
Testing for key C:\ProgramData\docker\certs.d\key.pem
False
Testing for key C:\ProgramData\docker\certs.d\cert.pem
False
Testing for key C:\ProgramData\docker\certs.d\ca.pem
False
答案 2 :(得分:0)
您可以索引到数组。查看 <input class="form-radio" type="radio" name="attribute[12175]" value="1061" id="attribute_1061" required>
<label class="form-option form-option-swatch" for="attribute_1061" data-product-attribute-value="1061">
<span class='form-option-variant form-option-variant--color tooltip' title="Graphite (PMS Black 7)" style="background-color: #4E4B49"></span>
</label>
$json.GetType()
答案 3 :(得分:0)
最简单的方法应该是这样
'exclude_cats' => '',
'layout' => 'large',
'meta_all' => 'yes',
'meta_author' => 'yes',
'meta_categories' => 'yes',
'meta_comments' => 'yes',
'meta_date' => 'yes',
'meta_link' => 'yes',
'meta_read' => 'yes',
'meta_tags' => 'no',
'number_posts' => '6',
'offset' => '',
'order' => 'DESC',
'orderby' => 'date',
'paging' => 'yes',
'show_title' => 'yes',
'scrolling' => 'infinite',
'strip_html' => 'yes',
'thumbnail' => 'yes',
'title_link' => 'yes',
'posts_per_page' => '6',
'taxonomy' => 'category',
'excerpt_words' => '50', //deprecated
'title' => '', // deprecated
), $args
);
答案 4 :(得分:0)
您可以使用ForEach-Object,即:
$json | ForEach-Object -Process { Write-Hoste $_; }
我相信这是最简单的方法,如果数组包含具有其他属性的对象,则可以轻松访问属性。