Home > Enterprise >  PowerShell for loop not adding last value from previously looped arrays
PowerShell for loop not adding last value from previously looped arrays

Time:04-12

I am totally stumped. I am reading data from an XML file into two separate arrays, which is then grouped together in a third array by indices (i.e. ($array-element[0], $array2-element[0])):

This is what my XML kinda looks like:

XML

<RESULTS>
    <ROW>
        <COLUMN NAME="ATTR1"><![CDATA[123456ABCDEF]]></COLUMN>
        <COLUMN NAME="ATTR2"><![CDATA[0.0.0.0]]></COLUMN>
        <COLUMN NAME="ATTR3"><![CDATA[Hello World]]></COLUMN>
        <COLUMN NAME="ATTR4"><![CDATA[Lorem ipsum]]></COLUMN>
        <COLUMN NAME="ATTR5"><![CDATA[This is some text]]></COLUMN>
    </ROW>
</RESULTS>

This is my PowerShell script that reads ATTR2 and ATTR3 into two separate arrays:

PowerShell (first two arrays)

$array = @()
$array2 = @()

foreach ($name in $xmldata.RESULTS.ROW.COLUMN.Where{ $_.NAME -eq "ATTR3"}.'#cdata-section')
{
    $array  = $name
}

foreach ($version in $xmldata.RESULTS.ROW.COLUMN.Where{ $_.NAME -eq "ATTR2"}.'#cdata-section')
{
    $array2  = $version
}

It returns the desired result.

Then I group the matching indices from each array into a new array ($array3):

PowerShell (third array)

$array3 = @()

for($i = 0; $i -lt $array.Length; $i  )
{
    $array3  = $array[$i]   ", "   $array2[$i]
    $i  
}

It returns the desired result (see below):

Result

Hello World, 0.0.0.0
(so on and so forth...)

However, the last for-loop refuses to add the last values from $array and $array2 into $array3.

$array.Length tells me the length of $array and $array2 are 896 even though there are only 895 elements. When I return $array[896] I get zero results. When I return $array[895] it returns the last value I am looking for.

And if the length of the array is indeed 896, then $i should stop at 895, correct? So, I assume it would be grabbing the final value (indexed at 895). So, why is my for-loop not adding the final value?

CodePudding user response:

The immediate problem with your for loop is that you've already specified that $i should be executed after each iteration in the loop signature ($i = 0; $i -lt $array.Length; $i ), but then you manually call $i inside the body as well.

That being said, the real solution is to not split the columns into 2 arrays in the first place. Instead, create a new object for each ROW node in the XML when you first iterate over it:

# assign all output from `foreach` loop to `$array`
$array = foreach($row in $xmldata.RESULTS.ROW){
  # create new object with the pertinent details as property values
  [pscustomobject]@{
    Name = $row.COLUMN.Where{ $_.NAME -eq "ATTR3"}.'#cdata-section'
    Version = $row.COLUMN.Where{ $_.NAME -eq "ATTR2"}.'#cdata-section'
  }
}

Now, $array will contain one object per ROW node, each with their own Name and Version property

  • Related