In the XML file documented below I need to do the following:
The XML file has the following content:
<?xml version="1.0" encoding="UTF-8"?>
<P3Dcontrol>
<General>
<Mode name="Day">
<P3DVersion>v4</P3DVersion>
<FlightFile>Maule-LSZH-Schoen.fxml</FlightFile>
<TacPackState>Inactive</TacPackState>
</Mode>
<Mode name="Evening">
<P3DVersion>v4</P3DVersion>
<FlightFile>Maule-LSZH-Schoen.fxml</FlightFile>
<TacPackState>Active</TacPackState>
</Mode>
</General>
<Exceptions>
<Weekday name="Monday">
<Mode name="Evening">
<P3DVersion>v4</P3DVersion>
<FlightFile>Maule-LSZH-Schoen.fxml</FlightFile>
<TacPackState>Inactive</TacPackState>
</Mode>
</Weekday>
<Date name="27.10.2020">
<Mode name="Day">
<P3DVersion>v5</P3DVersion>
<FlightFile>Maule-LSZH-Schoen.fxml</FlightFile>
<TacPackState>Inactive</TacPackState>
</Mode>
</Date>
</Exceptions>
</P3Dcontrol>
I setup the code to read the client nodes of a node I know exists but I have not been successful; the results in the array $controlData are all empty:
# Set up working data
$mode = GetCurrentMode # get current mode ('Day' or 'Evening')
$controlData = @{} # initialise array for data read
# Set up new XML object and read control file content
$xmlControl = New-Object System.XML.XMLDocument
$xmlControl.Load($controlFileSpec)
# Get <General>.<Mode name=$mode> node content
$xmlControl.P3Dcontrol.General.SelectSingleNode("Mode[@Name = $mode]") | ForEach-Object {
$controlData["P3DVersion"] = $_.P3DVersion
$controlData["FlightFile"] = $_.FlightFile
$controlData["TacPackState"] = $_.TacPackState
}
Thanks a lot for your help or hints Hannes
Once you have the XML document in $xmlControl, you should be able to work with it using standard PowerShell constructs. Perhaps something like this:
$controlData = $xmlControl.P3Dcontrol.General.Mode | Where-Object { $_.Name -eq $mode } | Select-Object P3DVersion,FlightFile,TacPackState
You can also save a line or two by using [xml]
to parse XML data.
edit:
The above line will get you a custom Powershell object, where you can access the properties as $controlData.P3DVersion
, $controlData.FlightFile
, etc. If you need to have an array, you can keep the ForEach-Object
part from your original code. Something like this:
$xmlControl.P3Dcontrol.General.Mode | Where-Object { $_.Name -eq $mode } | ForEach-Object {
$controlData["P3DVersion"] = $_.P3DVersion
$controlData["FlightFile"] = $_.FlightFile
$controlData["TacPackState"] = $_.TacPackState
}
You can do the following to update your hash table:
$mode = 'Day'
$controlData = @{}
$controlFileSpec = 'c:\temp\x.xml'
$xmlControl = New-Object System.XML.XMLDocument
$xmlControl.Load($controlFileSpec)
$xmlControl.P3Dcontrol.General.SelectSingleNode("Mode[@name = '$mode']") | ForEach-Object {
$controlData["P3DVersion"] = $_.P3DVersion
$controlData["FlightFile"] = $_.FlightFile
$controlData["TacPackState"] = $_.TacPackState
}
String values in XPATH expressions need to be quoted. Since your XPATH expression contains outer double quotes, then variables will be substituted inside. You can then just use single quotes around your variables that represent values.
XPATH expressions are case-sensitive. So @Name
and @name
are different. Since your XML contains lowercase name
attributes, you will need to match that in your expression.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.