'PowerShell for loop not adding last value from previously looped arrays
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?
Solution 1:[1]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mathias R. Jessen |
