I'm currently trying to get a Powershell script to extract information from an XML file and I've been trying a few different things like Select-Xml and SelectNodes, but I'm struggling. The information is in a format like this:
<school>
<students>
<student name="Bob" subject="Math" year="5">
<details SID="38571273" code="1122" group="" />
</student>
<student name="John" subject="Science" year="5">
<details SID="38343555" code="1123" group="" />
</student>
</students>
</school>
I want to extract information like the name, subject, year, SID, code, and group and store it in an array for each student so I can process it. I'm writing a Powershell script to do this, but I'm quite new to it, as well as XML. Any help would be greatly appreciated!
CodePudding user response:
For simple tasks like this one, you can access the XML items with dot notation, i.e. $xml.school.students.student
will give an array of <student>
elements.
After that, you can use select
(aka Select-Object
) to pick out certain properties. Either direct properties by name, or name/expression pairs (@{name='...', expression={...}}
for more complex ones, or if you want to rename the result "columns":
$xml.school.students.student | select name,subject,year,@{n='SID'; e={$_.details.SID}}
gives an array of PSCustomObject
s:
name subject year SID ---- ------- ---- --- Bob Math 5 38571273 John Science 5 38343555
CodePudding user response:
With the updated XML I revised my answer -
I think this is what you're looking for. You would just have to update the path to your xml.
$XMLPath = "ENTER_PATH"
function Get-StudentInfo {
param (
$xPATH,
$title)
Select-Xml -Path $XMLPath -XPath "/school/students/$xPATH" | ForEach-Object { $_.Node.$title }
}
$students = [PSCustomObject]@{
Names = Get-StudentInfo -xPath "student" -title "name"
Subjects = Get-StudentInfo -xPath "student" -title "subject"
Years = Get-StudentInfo -xPath "student" -title "year"
SIDs = Get-StudentInfo -xPath "student/details" -title "SID"
Codes = Get-StudentInfo -xPath "student/details" -title "code"
Groups = Get-StudentInfo -xPath "student/details" -title "group"
}
$students.Names
From there you would have an object $students
that has properties with an array for each property.
Names : {Bob, John}
Subjects : {Math, Science}
Years : {5, 5}
SIDs : {38343555, 38343555}
Codes : {1123, 1123}
Groups : {, }
To get a list of all the students names you would use $students.names
or for subject $students.subjects
A version that loads the XML file only once, instead of once per call to Get-StudentInfo
:
$students = Select-Xml -Path "test.xml" -XPath '/school/students/student' | Select-Object @(
@{name='Name'; expr={ $_ | Select-Xml '@name' }}
@{name='Subject'; expr={ $_ | Select-Xml '@subject' }}
@{name='Year'; expr={ $_ | Select-Xml '@year' }}
@{name='SID'; expr={ $_ | Select-Xml 'details/@SID' }}
@{name='Code'; expr={ $_ | Select-Xml 'details/@code' }}
@{name='Group'; expr={ $_ | Select-Xml 'details/@group' }}
)
$students
result
Name Subject Year SID Code Group ---- ------- ---- --- ---- ----- Bob Math 5 38571273 1122 John Science 5 38343555 1123