说我有JSON喜欢:
{
"a" : {
"b" : 1,
"c" : 2,
}
}
Run Code Online (Sandbox Code Playgroud)
现在很ConvertTo-Json乐意创造PSObjects出来.我想访问我能做的项目$json.a.b并得到1 - 很好的嵌套属性.
现在,如果我有字符串"a.b",问题是如何使用该字符串访问该结构中的相同项目?似乎应该有一些特殊的语法我缺少像&动态函数调用,因为否则你必须自己Get-Member反复使用我期望的解释字符串.
不,没有特殊的语法.
在最简单的解决方案是使用Invoke-Expression,这是在这种情况下受限的罚款,但Invoke-Expression通常应避免:
$json = @'
{
"a" : {
"b" : 1,
"c" : 2,
}
}
'@
$obj = ConvertFrom-Json $json
# The path to the target property.
$propertyPath = 'a.b'
# NOTE: In general, AVOID Invoke-Expression
# Construct the expression and pass it to Invoke-Expression.
# Note the need to `-escape the `$` in `$obj` to prevent premature expansion.
Invoke-Expression "`$obj.$propertyPath"
Run Code Online (Sandbox Code Playgroud)
以上相当于Invoke-Expression直接执行和收益$obj.a.b..
或者,您可以编写一个简单的辅助函数:
function propByPath($obj, $propertyPath) {
foreach ($prop in $propertyPath -split '\.') { $obj = $obj.$prop }
$obj # output
}
Run Code Online (Sandbox Code Playgroud)
而不是1你将使用的电话:
propByPath $obj $propertyPath
Run Code Online (Sandbox Code Playgroud)
您甚至可以使用PowerShell的ETS(扩展类型系统)将Invoke-Expression方法附加到所有.GetPropByPath()实例(PSv3 +语法;在PSv2中,您必须创建一个[pscustomobject]文件并加载它*.types.ps1xml):
'System.Management.Automation.PSCustomObject',
'Deserialized.System.Management.Automation.PSCustomObject' |
Update-TypeData -TypeName { $_ } `
-MemberType ScriptMethod -MemberName GetPropByPath -Value { #`
param($propPath)
$obj = $this
foreach ($prop in $propPath -split '\.') { $obj = $obj.$prop }
$obj # output
}
Run Code Online (Sandbox Code Playgroud)
然后你可以打电话Update-TypeData -PrependPath.
注意:$obj.GetPropByPath('a.b')除了Deserialized.System.Management.Automation.PSCustomObject还要包括反序列化的自定义对象之外,还会定位类型,这些对象在许多方案中返回,例如使用System.Management.Automation.PSCustomObject,接收后台作业的输出以及使用远程处理.
Import-CliXml将.GetPropByPath()在会话的剩余部分中的任何实例上可用(即使在[pscustomobject]调用之前创建的实例[1]); 将Update-TypeData调用放在您的Update-TypeData(配置文件)中以使该方法默认可用.
支持更健壮的解决方案的索引并保留阵列值属性为这样的
以上解决方案:
$PROFILE)以下解决方案修复了这些限制,但请注意:
仅支持文字标量索引(即,您可以使用'a.b[2]',但不能'a.b[2]'或者'a.b[1..2]',例如)
对于作为哈希表的属性,请指定(文字)键名而不嵌入引号(例如,'a.b[1, 2]'); 请注意,您通常无法访问数字哈希表键,此外,您将无法通过索引访问有序哈希表的条目.
'System.Management.Automation.PSCustomObject',
'Deserialized.System.Management.Automation.PSCustomObject' |
Update-TypeData -TypeName { $_ } `
-MemberType ScriptMethod -MemberName GetPropByPath -Value { #`
param($propPath)
$obj = $this
foreach ($prop in $propPath -split '\.') {
# See if the property spec has an index (e.g., 'foo[3]')
if ($prop -match '(.+?)\[(.+?)\]$') {
$obj = $obj.($Matches.1)[$Matches.2]
} else {
$obj = $obj.$prop
}
}
# Output: If the value is a collection (array), output it as a
# *single* object.
if ($obj.Count) {
, $obj
} else {
$obj
}
}
Run Code Online (Sandbox Code Playgroud)
[1]验证(全部在一行)'a.ht[bar]',$co = New-Object PSCustomObject; Update-TypeData -TypeName System.Management.Automation.PSCustomObject -MemberType ScriptMethod -MemberName GetFoo -Value { 'foo' }; $co.GetFoo()即使foo在$co调用之前创建了哪些输出.
| 归档时间: |
|
| 查看次数: |
450 次 |
| 最近记录: |