You can take advantage of the fact that PowerShell's convenient, property-based adaptation of the XML DOM essentially ignores namespaces, allowing to you simply drill down to the element of interest by the unqualified element names:
([xml] (Get-Content -Raw file.xml)).OfficeConfig.services.service.url
By contrast, the XPath-based Select-Xml
cmdlet is namespace-aware, and therefore requires explicit namespace handling - or a workaround via the local-name()
function, as shown in Mathias R. Jessen's answer.
If you want to use proper namespace handling - which is ultimately more robust, but not always necessary - use the following:
(
Select-Xml '//o:url' file.xml -Namespace @{ o='urn:schemas-microsoft-com:office:office' }
).Node.InnerText
Note the need to pass a hashtable (@{ ... }
) that declares the namespace prefixes and URLs used, which is the prerequisite for being able to use the prefixes (o:
, in this case) in the XPath query.
- The prefix names need not match the ones in the original, as long as they're consistent with the
-Namespace
argument and are mapped to the original URLs.
Select-Xml
returns wrapper objects around the matched System.Xml.XmlNode
instances, so .Node
is required to access the latter, and .InnerText
then returns the node's text content.
- As an aside: This need to access
.Node
is inconvenient, as the typical use case is to care about the XmlNode
only; GitHub suggestion #13669 seeks to ease the pain via a
-Raw
switch that returs the XmlNode
instances directly.