To complement Mathias R. Jessen's helpful answer:
Your own approach would have worked too - although it is (a) a bit more obscure, and (b) relies on the target element to already contain text (which is true in your case):
$xmldata.usersettings.Language.'#text' = 'Swedish'
PowerShell's adaptation of the XML DOM (surfacing child elements and attributes as properties) is handy, but remembering the precise rules can be tricky:
If a given element only has no content or only text content (a text child node) and also no attributes, it surfaces as a string-valued property on its parent element.
You can directly assign a string to such a property to set its text content; e.g.:
$xml = [xml] '<usersettings><Language>English</Language></usersettings>'
$xml.usersettings.Language = 'Swedish'
$xml.OuterXml # output the XML for verification
By contrast, if an element has attributes and/or child elements, it surfaces as an XmlElement
-valued property.
A child text node, if any, is represented as adapted property .'#text'
(quoting needed), alongside adapted properties representing attributes and child elements, if any.
$xml = [xml] '<usersettings><Language type="String">English</Language></usersettings>'
# Due to presence of an *attribute*, assignment must now happen
# via a property.
# Property '#text' is the existing text child node (text content).
$xml.usersettings.Language.'#text' = 'Swedish'
$xml.OuterXml # output the XML for verification
Independently, you can use the type-native .InnerText
property to replace an element's current child nodes, if any, with a text node, as shown in Mathias' answer.
$xml = [xml] '<usersettings><Language type="String">English</Language></usersettings>'
# Due to presence of an *attribute*, assignment must now happen
# via a property.
# Property .InnerText replaces all child nodes, if any, with
# a child text node (text content).
$xml.usersettings.Language.InnerText = 'Swedish'
$xml.OuterXml # output the XML for verification
In short:
When using PowerShell's property-based adaptation of the XML DOM, you need to be aware of when an XML element becomes a property of type [string]
- to which you can assign a string directly - vs. when it becomes an XmlElement
-typed property - which requires use of another property to assign text content.
That other property can be .'#text'
, if there's existing text content (a text child node) or - independently of any existing child nodes - .InnerText
, but note that the latter quietly replaces any existing child nodes, including element child nodes.