我正在做的事情是我将XML文档拆开并将一些元素的文本内容写到文件中。加载XML文档后,基本方法很简单:我要做的只是
$DI_XMLResponse.result.gudid.device.versionModelNumber | Out-File -FilePath $OutputFile -Append -NoClobber -Encoding ascii
但是,如果leaf元素不存在或根本不存在,我需要安排一个空白行。
我可以将内容分配给变量,测试变量是否为null,如果是,则将其设为空字符串,然后将其写出到文件中,
$foo = $DI_XMLResponse.result.gudid.device.versionModelNumber
if (!$foo) $foo = ''
$foo | Out-File -FilePath $OutputFile -Append -NoClobber -Encoding ascii
但是我希望找到一些更紧凑的表达方式。有一个吗?
答案 0 :(得分:5)
不幸的是, PowerShell没 没有ternary [conditional] operator(例如,
condition ? if-true-value : else-value
或null-coalescing operator(例如,
possiblyNullValue ?? valueIfNull
)(自PowerShell Core 6.1.0起)。
但是,请增强语言以支持这些is being proposed。
如果您希望看到这种情况发生,请在此听到您的声音-甚至是简单的“竖起大拇指”的帮助。
在您的特定情况下,您正在寻找 null-coalescing 操作符,并且-次优-解决方法:>
定义自定义函数,如Ryan Schlueter's answer所示,用于三元运算符。
对于 null-coalescing 运算符,它可能类似于:
function ?? ($PossiblyNull, $ValueIfNull) {
if ($null -eq $PossiblyNull) { $ValueIfNull } else { $PossiblyNull }
}
应用于您的代码:
?? $DI_XMLResponse.result.gudid.device.versionModelNumber '' |
Out-File -FilePath $OutputFile -Append -NoClobber -Encoding ascii
自定义功能的缺点是:
您需要将其包含或导入到要使用它们的每段代码中。
如果您选择熟悉的名称,例如?:
和??
,则操作数的位置会引起混淆,因为您必须(始终)将它们不同地放置在PowerShell,以实现为 function (例如,
C#中的a ?? b
与PowerShell中的?? $a $b
)。
使用 helper数组进行隐式布尔到整数转换:
$foo = $DI_XMLResponse.result.gudid.device.versionModelNumber
($foo, '')[$null -eq $foo] | Out-File -FilePath $OutputFile -Append -NoClobber -Encoding ascii
($foo, '')
是一个包含两个可能输出的值的数组。$null -eq $foo
是有条件的,如果$False
为$foo
,则求和为$null
,否则为$False
$null
是有意放置在LHS上的,因为如果$foo
恰好是 array 值,在RHS上它将执行不同的测试。[int]
值,因此$True
会自动转换为1
,而$False
结果在0
中。$foo
为$null
,则输出''
;否则,将按原样使用$foo
。此方法的缺点:
未应用短路逻辑;也就是说,在选择适当的元素之前,将无条件地对这两个数组元素进行评估
如果只需要 null-coalescing ,则必须先存储值以测试$null
在变量中;例如模仿
(Get-Foo Bar) ?? '(none)'
您必须首先将Get-Foo Bar
的输出保存在辅助变量中,以便您可以编写:
$aux = Get-Foo Bar; ($aux, '(none)')[$null -eq $aux]
答案 1 :(得分:1)
这是我要添加的小cmdlet。 PowerShell Inline If (IIf)
$foo = $null;
Write-Host (IIf $foo "True" "False")
Function IIf($If, $Right, $Wrong) {If ($If) {$Right} Else {$Wrong}}
答案 2 :(得分:1)
赋值可以作为表达式求值。这对您意味着什么,如果您只关心简洁而不是可读性,则可以改变您所做的事情:
if (-not ($foo = $xml. ...)) {
$foo = ''
}