PowerShell 语法类似于 :?操作员? [重复]

问题描述 投票:0回答:3

我正在做一件事情,我拆开一个 XML 文档并将某些元素的文本内容写入文件。一旦加载了 XML 文档,基本方法就非常简单:我所做的就是类似

$DI_XMLResponse.result.gudid.device.versionModelNumber | Out-File -FilePath $OutputFile -Append -NoClobber -Encoding ascii

但我需要安排在叶元素没有内容或根本不存在的情况下发出空行。

我可以将内容分配给一个变量,测试该变量是否为空,如果是则将其设置为空字符串,然后将其写入文件,

$foo = $DI_XMLResponse.result.gudid.device.versionModelNumber 
if (!$foo) $foo = ''
$foo | Out-File -FilePath $OutputFile -Append -NoClobber -Encoding ascii

但我希望找到一些更紧凑的表达方式。有吗

powershell ternary-operator null-coalescing-operator
3个回答
9
投票

更新

  • PowerShell(核心)7.0引入了三元运算符
    (

    $condition ? $valueIfTrue : $valueIfFalse
    )和空合并运算符
    $possibleNullValue ?? $valueIfNull
    $possibleNullValue ??= $valueIfNull
    }

  • PowerShell(核心)7.1引入了null条件运算符

    ${possibleNullValue}?.Property
    ${possibleNullValue}?[0]

    • 请注意变量名称周围需要使用
      {...}
      ,因为 - 与直觉相反 -
      ?
      目前是合法的变量名称字符 - 请参阅 GitHub 问题 #14025

本答案的其余部分显示了模拟三元运算符和Windows PowerShell的空合并(以及现在已过时的PowerShell(核心)版本6.x及更早版本)的方法:


不幸的是,

Windows PowerShell没有三元[条件]运算符(例如,
$condition ? $valueIfTrue : $valueIfFalse

)或 
空合并运算符(例如,
$possibleNullValue ?? $valueIfNull
.

在您的具体情况下,

您正在寻找 null-coalescing 运算符,并且有 - 次优 - 解决方法


定义一个自定义函数,如 Ryan Schlueter 对 ternary 运算符的回答所示。

对于

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 中以不同的方式放置它们,假设实现为 函数(例如, C# 中的 a ?? b
    与 PowerShell 中的
    ?? $a $b
    )。
    
    

使用带有隐式布尔到整数转换的
辅助数组

: $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上的,因为在RHS上,如果
      $foo
      碰巧是
      array
      值,它将执行不同的测试。
  • 数组索引
  • 的上下文中,需要一个[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
投票
PowerShell 内联 If (IIf)

$foo = $null; Write-Host (IIf $foo "True" "False") Function IIf($If, $Right, $Wrong) {If ($If) {$Right} Else {$Wrong}}



1
投票

if (-not ($foo = $xml. ...)) { $foo = '' }

© www.soinside.com 2019 - 2024. All rights reserved.