在 PowerShell 中按名称设置嵌套对象 属性 的值
Set Value of Nested Object Property by Name in PowerShell
我想使用 PowerShell 设置嵌套对象的值 属性。当您尝试设置第一级属性的值时,它非常简单:
$propertyName = "someProperty"
$obj.$propertyName = "someValue" # ← It works
对于嵌套属性,它不起作用:
$propertyName = "someProperty.someNestedProperty"
$obj.$propertyName = "someValue" # ← It doesn't work and raises an error.
如何使用 PowerShell 按 属性 的名称设置嵌套对象 属性 的值?
MCVE
对于那些想重现问题的人,这里有一个简单的例子:
$Obj= ConvertFrom-Json '{ "A": "x", "B": {"C": "y"} }'
# Or simply create the object:
# $Obj= @{ A = "x"; B = @{C = "y"} }
$Key = "B.C"
$Value = "Some Value"
$Obj.$Key = $Value
运行 命令,您将收到错误消息:
"The property 'B.C' cannot be found on this object. Verify that the
property exists and can be set."
注意:代码支持任意层级嵌套
我创建了 SetValue
和 GetValue
函数,让您可以通过名称动态获取和设置对象(包括 json 对象)的嵌套 属性,它们工作完美!
它们是递归函数,通过拆分嵌套的属性名称,逐步解析复杂的属性并得到嵌套的属性。
按名称获取嵌套属性的值和设置值
# Functions
function GetValue($object, $key)
{
$p1,$p2 = $key.Split(".")
if($p2) { return GetValue -object $object.$p1 -key $p2 }
else { return $object.$p1 }
}
function SetValue($object, $key, $Value)
{
$p1,$p2 = $key.Split(".")
if($p2) { SetValue -object $object.$p1 -key $p2 -Value $Value }
else { $object.$p1 = $Value }
}
例子
在下面的示例中,我使用 SetValue
动态设置 B.C
并使用 GetValue
函数按名称获取其值:
# Example
$Obj = ConvertFrom-Json '{ "A": "x", "B": {"C": "y"} }'
# Or simply create the object:
# $Obj = @{ A = "x"; B = @{C = "y"} }
$Key = "B.C"
$Value = "Changed Dynamically!"
SetValue -object $Obj -key $Key -Value $Value
GetValue -object $Obj -key $Key
我可以提议升级 Reza 的解决方案吗?使用此解决方案,您可以拥有多级嵌套属性。
function GetValue($object, [string[]]$keys)
{
$propertyName = $keys[0]
if($keys.count.Equals(1)){
return $object.$propertyName
}
else {
return GetValue -object $object.$propertyName -key ($keys | Select-Object -Skip 1)
}
}
function SetValue($object, [string[]]$keys, $value)
{
$propertyName = $keys[0]
if($keys.count.Equals(1)) {
$object.$propertyName = $value
}
else {
SetValue -object $object.$propertyName -key ($keys | Select-Object -Skip 1) -value $value
}
}
用法
$Obj = ConvertFrom-Json '{ "A": "x", "B": {"C": {"D" : "y"}} }'
SetValue $Obj -key "B.C.D".Split(".") -value "z"
GetValue $Obj -key "B.C.D".Split(".")
您的 有效,但不支持 indexed access 作为嵌套 属性 的一部分-访问路径(例如,B[1].C
)
一个简单的替代方法是使用Invoke-Expression
(iex
)。
虽然它 ,但在某些特殊情况下它提供了最简单的解决方案,这就是其中之一:
假设您完全控制或隐式信任 属性-访问字符串:
$obj = ConvertFrom-Json '{ "A": "x", "B": [ {"C": "y"}, { "C": "z"} ] }'
$propPath = 'B[1].C'
# GET
Invoke-Expression "`$obj.$propPath" # -> 'z'
# SET
$value = 'Some Value'
Invoke-Expression "`$obj.$propPath = `$value"
如果您不信任输入,您可以避免不需要的命令注入,如下所示:
$safePropPath = $propPath -replace '(`)*$', '`$$'
Invoke-Expression "`$obj.$safePropPath"
# ...
对于安全打包上述功能的便捷功能/ETS 方法,请参阅。
我想使用 PowerShell 设置嵌套对象的值 属性。当您尝试设置第一级属性的值时,它非常简单:
$propertyName = "someProperty"
$obj.$propertyName = "someValue" # ← It works
对于嵌套属性,它不起作用:
$propertyName = "someProperty.someNestedProperty"
$obj.$propertyName = "someValue" # ← It doesn't work and raises an error.
如何使用 PowerShell 按 属性 的名称设置嵌套对象 属性 的值?
MCVE
对于那些想重现问题的人,这里有一个简单的例子:
$Obj= ConvertFrom-Json '{ "A": "x", "B": {"C": "y"} }'
# Or simply create the object:
# $Obj= @{ A = "x"; B = @{C = "y"} }
$Key = "B.C"
$Value = "Some Value"
$Obj.$Key = $Value
运行 命令,您将收到错误消息:
"The property 'B.C' cannot be found on this object. Verify that the property exists and can be set."
注意:代码支持任意层级嵌套
我创建了 SetValue
和 GetValue
函数,让您可以通过名称动态获取和设置对象(包括 json 对象)的嵌套 属性,它们工作完美!
它们是递归函数,通过拆分嵌套的属性名称,逐步解析复杂的属性并得到嵌套的属性。
按名称获取嵌套属性的值和设置值
# Functions
function GetValue($object, $key)
{
$p1,$p2 = $key.Split(".")
if($p2) { return GetValue -object $object.$p1 -key $p2 }
else { return $object.$p1 }
}
function SetValue($object, $key, $Value)
{
$p1,$p2 = $key.Split(".")
if($p2) { SetValue -object $object.$p1 -key $p2 -Value $Value }
else { $object.$p1 = $Value }
}
例子
在下面的示例中,我使用 SetValue
动态设置 B.C
并使用 GetValue
函数按名称获取其值:
# Example
$Obj = ConvertFrom-Json '{ "A": "x", "B": {"C": "y"} }'
# Or simply create the object:
# $Obj = @{ A = "x"; B = @{C = "y"} }
$Key = "B.C"
$Value = "Changed Dynamically!"
SetValue -object $Obj -key $Key -Value $Value
GetValue -object $Obj -key $Key
我可以提议升级 Reza 的解决方案吗?使用此解决方案,您可以拥有多级嵌套属性。
function GetValue($object, [string[]]$keys)
{
$propertyName = $keys[0]
if($keys.count.Equals(1)){
return $object.$propertyName
}
else {
return GetValue -object $object.$propertyName -key ($keys | Select-Object -Skip 1)
}
}
function SetValue($object, [string[]]$keys, $value)
{
$propertyName = $keys[0]
if($keys.count.Equals(1)) {
$object.$propertyName = $value
}
else {
SetValue -object $object.$propertyName -key ($keys | Select-Object -Skip 1) -value $value
}
}
用法
$Obj = ConvertFrom-Json '{ "A": "x", "B": {"C": {"D" : "y"}} }'
SetValue $Obj -key "B.C.D".Split(".") -value "z"
GetValue $Obj -key "B.C.D".Split(".")
您的 B[1].C
)
一个简单的替代方法是使用Invoke-Expression
(iex
)。
虽然它
假设您完全控制或隐式信任 属性-访问字符串:
$obj = ConvertFrom-Json '{ "A": "x", "B": [ {"C": "y"}, { "C": "z"} ] }'
$propPath = 'B[1].C'
# GET
Invoke-Expression "`$obj.$propPath" # -> 'z'
# SET
$value = 'Some Value'
Invoke-Expression "`$obj.$propPath = `$value"
如果您不信任输入,您可以避免不需要的命令注入,如下所示:
$safePropPath = $propPath -replace '(`)*$', '`$$'
Invoke-Expression "`$obj.$safePropPath"
# ...
对于安全打包上述功能的便捷功能/ETS 方法,请参阅