Determine XML Node Exists
The easiest way I can think of is to try to write the node value to a variable, and then to see if that variable is null. Here's an example with the standard bookstore xml file.
[xml]$bookstore = Get-Content .\bookstore.xmlforeach ($book in $bookstore.bookstore.book | Where-Object {$_.Type -match "novel"}) { $NodeExists = $book.author if($NodeExists){ Write-Host $book.author } else{ Write-Host 'No Author' }}
So for your script, I would think it might be
$NodeExists = $nullforeach ($vendor in $xml.Vendors.Vendor| Where-Object {$_.Type -match "Send"}) { $NodeExists = $vendor.EncKey if ($NodeExists) { # Do something } else { # something else }}
It appears that I was using the wrong syntax for SelectSingleNode. Here is a working example.
[xml]$xml = @'<?xml version="1.0" encoding="UTF-8"?> <!-- Vendors we will send and retreive files from Get-Send means we will get a file and send them a file Send means we will only send them a file--> <Vendors> <Vendor Type="Get-Send"> <Name>Vendor1</Name> <RemotePath>/Remote/Path1/</RemotePath> <EncKey>pgpenc.key</EncKey> </Vendor> <Vendor Type="Send"> <Name>Vendor2</Name> <RemotePath>/Remote/Path2/</RemotePath> <!-- This one has no EncKey --> </Vendor> </Vendors>'@foreach ($vendor in $xml.Vendors.Vendor| Where-Object {$_.Type -match "Send"}) { $NodeExists = $vendor.SelectSingleNode("./EncKey") if ($NodeExists -ne $null) { write-host "EncKey is null" } else { write-host "EncKey is not null" } }EncKey is nullEncKey is not null
Thanks everyone for your help.
Use XPath to select matching nodes. InnerText is searchable by text()
. You can use where-object
, or ?
too; behaviour is a bit different. Without sample XML it's hard to be more precise. Use XPath like so,
[xml]$doc = @'<root><Vendors><Vendor><Type>Send</Type></Vendor><Vendor><Type>Receive</Type></Vendor></Vendors></root>'@# Xpath query will return a NodeList, even if no match is found$node1 = $doc.SelectNodes("//Vendor/Type[text() = 'Send']")$node2 = $doc.SelectNodes("//Vendor/Type[text() = 'Sent']")$node1.Count1$node2.Count0# where-object will return $null if no match is found$node1 = $doc.SelectNodes("//Vendor/Type") | ? { $_.InnerText -eq "Send" }$node2 = $doc.SelectNodes("//Vendor/Type") | ? { $_.InnerText -eq "Sent" }$node1 -eq $nullFalse$node2 -eq $nullTrue