Assume I have this XML file:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="book1">
<chapters>
<chapter1>Begin</chapter1>
<chapter2>mid</chapter2>
<chapter3>end</chapter3>
</chapters>
<pages>352</pages>
</book>
<book id="book2">
<chapters>
<chapter1>woop</chapter1>
<chapter2>doop</chapter2>
<chapter3>goop</chapter3>
</chapters>
<pages>761</pages>
</book>
</books>
Now I want to read this with PowerShell, e.g.:
$file = "C:\path\books.xml"
$xml = [xml](Get-Content $file)
$books = $xml.books.book.id
foreach ($book in $books) {
...
}
In the loop I want to get the chapters of each book, so I tried this:
$xml.books.book | ? {$_.id -eq $book} | select chapters.chapter1
but that didn't work. So I tried this instead:
(xml.books.book | where $_.id -eq $book).chapters.chapter1
Both won't work for some reason. How can I get these values?
Your first approach didn't work, because Select-Object
lets you select properties (chapters
), but not nested properties (chapters.chapter1
). You'd need to expand the properties and cascade the cmdlet calls to get the child property values:
$xml.books.book |
Where-Object {$_.id -eq $book} |
Select-Object -Expand chapters |
Select-Object -Expand chapter1
Your second approach didn't work, because you omitted the $
from $xml
and you didn't get the abbreviated Where-Object
syntax right. If you want to use short Where-Object
filter notation it's <cmdlet> <property> <op> <value>
without the current object variable ($_
):
($xml.books.book | Where-Object id -eq $book).chapters.chapter1
otherwise you need the regular syntax:
($xml.books.book | Where-Object {$_.id -eq $book}).chapters.chapter1
With that said, none of the approaches is very elegant. For your example scenario you could simply use dot-notation to get all <chapter1>
values:
$xml.books.book.chapters.chapter1
If you need more control it's usually more efficient to use XPath expressions, though, e.g. if you want a list of all book IDs:
$xml.SelectNodes('//book/@id') | Select-Object -Expand '#text'
or if you want to select the third chapter of the book with the ID "book2":
$id = 'book2'
$xml.SelectSingleNode("//book[@id='$id']/chapters/chapter3").'#text'
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments