Working with XML
Prerequisites: Working with JSON
Cast text to [xml] and PowerShell lets you navigate it with dots:
[xml]$doc = @'
<catalog>
<book id="1" lang="en">
<title>Learn PowerShell</title>
<price>29.99</price>
</book>
<book id="2" lang="fr">
<title>Apprendre Python</title>
<price>24.50</price>
</book>
</catalog>
'@
$doc.catalog.book.Count
$doc.catalog.book[0].title
$doc.catalog.book | ForEach-Object { '{0} ({1}): {2}' -f $_.title, $_.lang, $_.price }
2
Learn PowerShell
Learn PowerShell (en): 29.99
Apprendre Python (fr): 24.50
Elements and attributes both appear as properties ($_.lang is an
attribute).
XPath with Select-Xml
[xml]$doc = '<catalog><book lang="en"><title>A</title><price>30</price></book><book lang="fr"><title>B</title><price>20</price></book></catalog>'
$doc.SelectNodes('//book[price > 25]/title') | ForEach-Object InnerText
Select-Xml -Xml $doc -XPath '//book[@lang="fr"]/title' | ForEach-Object { $_.Node.InnerText }
A
B
Changing and saving
[xml]$doc = '<config><setting name="timeout">30</setting></config>'
$doc.config.setting.'#text' = '60'
$new = $doc.CreateElement('setting')
$new.SetAttribute('name', 'retries')
$new.InnerText = '3'
$doc.config.AppendChild($new) | Out-Null
$doc.OuterXml
<config><setting name="timeout">60</setting><setting name="retries">3</setting></config>
To load a file, use [xml](Get-Content config.xml -Raw); to save,
$doc.Save((Resolve-Path config.xml)) — Save needs a full path. Format
XML for reading with the XML Formatter.