I'm trying to save content from a single node to a variable from this xml content.
<?xml version="1.0"?>
<ProjectRuntimeInfo xmlns:xsd="http://www.test.org/20/test" xmlns:xsi="http://www.test.org/20/test">
<Guid>37968228-1bc9-4b84-9eaa-cf0b7ef1c70e</Guid>
<FileVersion>8.05.5006.24</FileVersion>
<LastFullPublishDate>2023-10-06T14:00:01.8704004+02:00</LastFullPublishDate>
<SolutionPath>C:\Users\Public\Documents\Projects\Programm\</SolutionPath>
<SolutionName>Produktion</SolutionName>
<LastUser>Administrator</LastUser>
<MasterProjekt>Produktion</MasterProjekt>
</ProjectRuntimeInfo>
The node in question is "SolutionPath" and the Information I need saved is
C:\Users\Public\Documents\Projects\Programm\
I read the xml with
[xml]$xml = Get-Content -Path '.\AppInfo.xml'
But I can't seem to find a way to get the desired node saved to the same or another variable since the nodes I supposedly have to navigate through to get to "SolutionPath" are very rich in text. So if I'm correct I somehow have to navigate through them like the following?
$xml.ProjectRuntimeInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance".SolutionPath
But that seems rather odd to me. Thankful for any help <3
PowerShell allows you to treat any parsed [xml]
document as an object graph that you can drill into using regular dot notation, because PowerShell surfaces XML (child) elements and XML attributes as namespace-less properties on each object (XML node) in the graph - see this answer for additional information.
While something like [xml]$xml = Get-Content -Path ...
is a convenient way to read an XML file into an [xml]
instance, it is best avoided, because it risks using the wrong character encoding - see this answer for additional information.
Therefore:
# Robustly load and parse the XML file.
($xml = [xml]::new()).Load((Convert-Path .\AppInfo.xml))
# Use dot notation (which is namespace-agnostic) to drill down to
# the element of interest.
$xml.ProjectRuntimeInfo.SolutionPath
Alternatively and more concisely, use Select-Xml
with an XPath query:
(
Select-Xml -LiteralPath .\AppInfo.xml '/ProjectRuntimeInfo/SolutionPath'
).Node.InnerText
Note:
Unlike the dot notation used in the first solution, Select-Xml
(as well as the underlying .NET APIs) is namespace-aware, which must be taken into account.
The only reason it isn't necessary here is that the target element is neither in a default namespace nor in an explicit one (via an element-name prefix).
For an example of a Select-Xml
solution that involves namespace handling, see this answer.