Alan Varga
asked on
Create PowerShell 2-Dimensional Array From XML Configuration File
How do I convert the child nodes for a specific computer in this configuration file to a 2-dimensional table? Here is the XML:
This code doesn't seem to allow accessing individual elements of a specific item:
The results I want are like this:
I have a Switch statement further on that will do something different with $SelectedItemText, depending on whether $SelectedItemType is a folder or a textfile.
My problem is that $Result returns the type and text together. Also, GridView lists the type column first and the #text column second. What I want returned is the #text# for the row I select.
<PsProjects>
<metadata>
<revdate>2017-04-14</revdate>
</metadata>
<computers>
<computer id="livingroom02">
<item type="folder">C:\Computer-livingroom02 SYS 033</item>
<item type="folder">C:\Computer-livingroom02 SYS 033\Hardware\Network Adapters</item>
<item type="folder">C:\Computer-livingroom02 SYS 033\Software</item>
<item type="folder">C:\Program2\Powershell</item>
<item type="folder">C:\Program2\Varga\Network Mapping</item>
<item type="folder">D:\Programming Languages\PowerShell</item>
<item type="textfile">PsProjects.xml</item>
</computer>
<computer id="work">
<item type="folder">C:\Computer</item>
<item type="folder">C:\AlansDownloads\Alan\_AlansBriefcase</item>
<item type="folder">C:\Computer\Hardware\Network Adapters</item>
<item type="folder">C:\Computer\Software</item>
<item type="folder">C:\Program2\Varga\Network Mapping</item>
<item type="folder">C:\Workshop\PowerShell-work</item>
<item type="textfile">PsProjects.xml</item>
</computer>
</computers>
</PsProjects>
This code doesn't seem to allow accessing individual elements of a specific item:
ForEach ( $computer in $ProjectsConfigFile.SelectNodes( "//PsProjects/computers/computer" ) ) {
$PsComputerName = $computer.Attributes['id'].Value
If ( $PsComputerName -eq $ThisComputerId ) {
$MatchingComputer = $computer
[array]$ProjectItems = $MatchingComputer.item
break
}
}
The results I want are like this:
$Result = $ProjectItems | Out-GridView -Passthru -Title "Select an item and click OK or press <Enter>, or press <Esc> to quit"
$Selection = [array]::IndexOf( $ProjectItems, $Result )
$SelectedItemText = $ProjectItems[$Selection].'#text'
$SelectedItemType = $ProjectItems[$Selection].type
#or
$SelectedItem = $ProjectItems[$Selection]
$SelectedItemText = $SelectedItem.'#text'
$SelectedItemType = $SelectedItem.type
I have a Switch statement further on that will do something different with $SelectedItemText, depending on whether $SelectedItemType is a folder or a textfile.
My problem is that $Result returns the type and text together. Also, GridView lists the type column first and the #text column second. What I want returned is the #text# for the row I select.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Can't reproduce, works just fine here. Are you using the xml you attached, and the exact script I posted? Does it display correctly in the GridView?
$ThisComputerId = 'work'
$ProjectsConfigFile = [xml](Get-Content -Path D:\Temp\PsProjects.xml)
$ComputerNode = $ProjectsConfigFile.SelectSingleNode("//PsProjects/computers/computer[@id='$($ThisComputerId)']")
$ProjectItems = $ComputerNode.SelectNodes('item') | Select-Object -Property @{n='Type'; e={$_.GetAttribute('type')}}, @{n='Text'; e={$_.InnerText}}
If ($Result = ($ProjectItems | Out-GridView -Title "Select an item and click OK or press <Enter>, or press <Esc> to quit" -OutputMode Single)) {
$SelectedItemType = $Result.Type
$SelectedItemText = $Result.Text
} Else {
Exit 1
}
"Selected Type: $($SelectedItemType)" | Write-Host
"Selected Text: $($SelectedItemText)" | Write-Host
ASKER
This is strange: I saved your most recent (re-)post on my computer at home, adjusted the computer id and the path for the configuration file and it worked without a hitch.
I will have to do some more troubleshooting at work on Monday. Thanks for your patience and guidance.
I will have to do some more troubleshooting at work on Monday. Thanks for your patience and guidance.
ASKER
I figured it out! Near the beginning of my script (which was not shown here) I was initializing some variables (a habit of VBA option explicit). My problem was
[string]$Result = ""
After I commented that out, $Result was allowed to be whatever it wanted to be (object? array?), everything worked as expected. Thanks for your help.
ASKER
This was understandable, short and to the point. Kudos for a well-written solution that worked as advertised.
ASKER
Open in new window
However, typing $Result. (note the period to prompt for properties), Intellisense only offers Length, Clone, etc.