首页 > 解决方案 > 有没有更好的方法让我在 PowerShell 中循环遍历 json 节点

问题描述

我想知道是否有人可以帮助我并提出建议。

我有一个如下所示的 JSON 文件,其中包含几个不同的节点,出于保密目的,我删除了这些值。我需要能够遍历 JSON 提供的每个测试步骤,并拉取状态为失败的步骤的测试。

到目前为止,我发现这样做最简单的方法是嵌套每个循环(报告-> 描述-> 元素-> 步骤-> 结果-> 状态)我想知道是否有任何 PowerShell 专家可以帮助我找到一个可能的更清洁和更快的解决方案?

[
  {
    "description": "",
    "elements": [
      {
        "description": "",
        "id": "",
        "keyword": "Scenario",
        "line": 9,
        "name": "",
        "tags": [
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          }
        ],
        "steps": [
          {
            "keyword": "Given ",
            "line": 0,
            "match": {
              "location": ""
            },
            "name": "",
            "result": {
              "duration": 41560.8294,
              "error_message": null,
              "status": "Failed"
            }
          }
        ],
    "name": "",
    "uri": ""
  },
  {
    "description": "",
    "elements": [
      {
        "description": "",
        "id": "",
        "keyword": "Scenario",
        "line": 14,
        "name": "",
        "tags": [
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          }
        ],
        "steps": [
          {
            "keyword": "Given ",
            "line": 0,
            "match": {
              "location": ""
            },
            "name": "",
            "result": {
              "duration": 17133.4242,
              "error_message": ,
              "status": ""
            }
          }
        ],
    "name": "",
    "uri": ""
  }
]
[String]$report = Get-Content $inputPath
[System.Object[]]$json = ConvertFrom-Json -InputObject "$report"

[String[]]$failedTests = @()

foreach($feature in $json)
{
    foreach($scenario in $feature.elements)
    {
        foreach($step in $scenario.steps)
        {
            if(($scenario.steps).Where({ $step.result.status -eq "Failed" }, 'First').Count -gt 0)
            {
                $failedTests += Generate-FullyQualifiedName $ProjectName $feature.name $scenario.name
                break
            }
        }
    }            
}

标签: jsonpowershellforeachnested-loops

解决方案


您所拥有的几乎是在 powershell 中返回对象的多个“深度”的最佳方法,因为实际上并没有 .

一项改进是强制 powershell 使用类型对象,而不是由 . 创建[list[]]的默认固定长度对象,每次使用. 相反,请尝试使用:[System.Array]$foo = @()+=

$failedTests = [System.Collections.Generic.List[String]]::new()

# loops...

$failedTests.Add((Generate-FullyQualifiedName -etc))

您也不需要遍历每个步骤来检查场景是否失败:

foreach($scenario in $feature.elements) {
  # -- Skip foreach $step
  if($scenario.steps.result.status -eq 'Failed') {
    $failedTests.Add((Generate-FullyQualifiedName -etc))
  }
}

对于大多数目的,我会坚持你正在做的循环。根据每个对象的实际大小,迭代数组索引 int 而不是将整个$feature对象分配给变量可能会更快(也更丑),但我怀疑它在这里会有多大帮助。


推荐阅读