powershell - цикл через XML создает правильное количество узлов, но значения атрибутов объединены

У меня есть эта функция Powershell:

function reportxml {

$logdir = "C:\\Documents\scriptOutput"
$XML_Path = $logdir + '\TR.xml'
$XML_NEW_PATH = $logdir + '\TestResult.xml'
$DLL_PATH = "tests.dll"
$xmlsettings = New-Object System.Xml.XmlWriterSettings
$xmlsettings.Indent = $true
$xmlsettings.IndentChars = "`t"
$XmlWriter = [System.XML.XmlWriter]::Create("$logdir\TestResult.xml", $xmlsettings)
$xmlWriter.WriteStartDocument()
$xmlWriter.WriteStartElement('assemblies')
$xmlWriter.WriteEndElement()
$xmlWriter.WriteEndDocument()
$xmlWriter.Flush()
$xmlWriter.Close()

$xmlOld = [System.Xml.XmlDocument](Get-Content $XML_Path);
$xmlDoc = [System.Xml.XmlDocument](Get-Content "$logdir\TestResult.xml");

$siteCollectionNode = $xmlDoc.CreateElement("assembly")
$xmlDoc.SelectSingleNode("//assemblies").AppendChild($siteCollectionNode)
$siteCollectionNode.SetAttribute("name", $DLL_PATH)
$siteCollectionNode.SetAttribute("total", $xmlOld.TestRun.ResultSummary.Counters.total)
$siteCollectionNode.SetAttribute("passed", $xmlOld.TestRun.ResultSummary.Counters.passed)
$siteCollectionNode.SetAttribute("failed", $xmlOld.TestRun.ResultSummary.Counters.failed)
$xmlDoc.Save($XML_NEW_PATH)

$siteCollectionNode.AppendChild($xmlDoc.CreateElement("errors"));
$xmlDoc.Save($XML_NEW_PATH)

$subSitesNode = $siteCollectionNode.AppendChild($xmlDoc.CreateElement("collection"))
$subSitesNode.SetAttribute("Name", "UAT Smoke Tests")
$subSitesNode.SetAttribute("total", $xmlOld.TestRun.ResultSummary.Counters.total)
$subSitesNode.SetAttribute("passed", $xmlOld.TestRun.ResultSummary.Counters.passed)
$subSitesNode.SetAttribute("failed", $xmlOld.TestRun.ResultSummary.Counters.failed)
$xmlDoc.Save($XML_NEW_PATH)

$TestResultNodes = $xmlOld.TestRun.Results.UnitTestResult 
 $TestResultNodes | ForEach-Object {
    $subSiteNameNode =  $subSitesNode.AppendChild($xmlDoc.CreateElement("test"));
    $subSiteNameNode.SetAttribute("method",$xmlOld.TestRun.Results.UnitTestResult.testName)
    $subSiteNameNode.SetAttribute("result", $xmlOld.TestRun.Results.UnitTestResult.outcome)

    $subSiteNameNode.AppendChild($xmlDoc.CreateElement("output"))
    $xmlDoc.Save($XML_NEW_PATH)

    $ListsElement =  $subSiteNameNode.AppendChild($xmlDoc.CreateElement("traits"));
    $ListElement = $ListsElement.AppendChild($xmlDoc.CreateElement("trait"));
    $ListElement.SetAttribute("name", "Category")
    $ListElement.SetAttribute("value", $xmlOld.TestRun.Results.UnitTestResult.testName)
    $xmlDoc.Save($XML_NEW_PATH)
}
return $XML_NEW_PATH

}

Работает почти нормально, просто помещает все значения testname и output в каждый атрибут name и value, например:

<collection Name="UAT Smoke Tests" total="12" passed="0" failed="12">
  <test method="Should_Search_LeaseByBookingStatusCommenced_Successfully Should_Search_LegalEntity_Successfully Should_Search_SequesnceNumberLease_Successfully Should_Search_PayableInvoice_Successfully Should_Search_CustomerByStatus_Successfully Should_Search_LeaseByBookingStatusPending_Successfully Should_Search_VendorByName_Successfully Should_Search_CustomerByNumber_Successfully Should_Search_VendorByNumber_Successfully Should_Search_CustomerByName_Successfully Should_Search_InvoiceNumber_Successfully Should_Search_CustomerByAlias_Successfully" result="Failed Failed Failed Failed Failed Failed Failed Failed Failed Failed Failed Failed">
    <output />
    <traits>
      <trait name="Category" value="Should_Search_LeaseByBookingStatusCommenced_Successfully Should_Search_LegalEntity_Successfully Should_Search_SequesnceNumberLease_Successfully Should_Search_PayableInvoice_Successfully Should_Search_CustomerByStatus_Successfully Should_Search_LeaseByBookingStatusPending_Successfully Should_Search_VendorByName_Successfully Should_Search_CustomerByNumber_Successfully Should_Search_VendorByNumber_Successfully Should_Search_CustomerByName_Successfully Should_Search_InvoiceNumber_Successfully Should_Search_CustomerByAlias_Successfully" />
    </traits>
  </test>
</collection>

Как мне получить первый набор значений в первом методе тестового тега и в атрибуте value(и, конечно, для атрибута Category tag), второй набор во вторых тегах и т. Д.?

Я исследовал это в Интернете, но не смог найти ничего похожего на этот случай, был бы очень признателен за помощь.

1 ответ

Я разобрался, оставив здесь решение для тех, кто находится в такой же ситуации. Я использовал массивы, чтобы сохранить значение каждого атрибута, и переключил ForEach-Object на простой цикл for. См. Только эту часть кода ниже:

  For ($i = 1; $i -lt $xmlOld.TestRun.ResultSummary.Counters.total; $i++ ) 
    {
        $testName = $xmlOld.TestRun.Results.UnitTestResult.testName
        $testOutcome = $xmlOld.TestRun.Results.UnitTestResult.outcome
        $testOutput = $xmlOld.TestRun.Results.UnitTestResult.Output.StdOut
        $arrayTestNames = @{}
        $arrayOutcomes = @{}
        $arrayOutput = @{}
        foreach ($item in $testName) {
            $hostname = $item.Node.InnerText.Trim()
            $services = @($item.Node.ParentNode.Service)
            foreach ($service in $services)
            {
            $arrayTestNames["$hostname"] += @($service.Trim())}
            }
            $arrayTestNames

        foreach ($result in $testOutcome) {
            $hostname = $result.Node.InnerText.Trim()
            $services = @($result.Node.ParentNode.Service)
            foreach ($service in $services)
            {
            $arrayOutcomes["$hostname"] += @($service.Trim())}
            }
            $arrayOutcomes
        foreach ($output in $testName) {
            $hostname = $output.Node.InnerText.Trim()
            $services = @($output.Node.ParentNode.Service)
            foreach ($service in $services)
            {
            $arrayOutput["$hostname"] += @($service.Trim())}
            }
            $arrayOutput

    $subSiteNameNode =  $subSitesNode.AppendChild($xmlDoc.CreateElement("test"));
    $subSiteNameNode.SetAttribute("method", $testName[$i])
    $subSiteNameNode.SetAttribute("result", $testOutcome[$i])
    
    $outputNode = $subSiteNameNode.AppendChild($xmlDoc.CreateElement("output"))
    $outputNode.AppendChild($xmlDoc.CreateTextNode($testOutput[$i])); 

    $xmlDoc.Save($XML_NEW_PATH)

    $ListsElement =  $subSiteNameNode.AppendChild($xmlDoc.CreateElement("traits"));
    $ListElement = $ListsElement.AppendChild($xmlDoc.CreateElement("trait"));
    $ListElement.SetAttribute("name", "Category")
    $ListElement.SetAttribute("value", $testName[$i])
    $xmlDoc.Save($XML_NEW_PATH)
    }

}

return $XML_NEW_PATH
Другие вопросы по тегам