说我有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 次 |
最近记录: |