C'est probablement simple, mais j'essaie de déterminer si un nœud existe dans un document XML. Je pensais avoir trouvé une réponse dans ce post, Comment vérifier si un nœud existe ou non en utilisant PowerShell sans obtenir d'exception? , mais je ne l'ai pas fait fonctionner. Ceci est ma dernière tentative.
foreach ($vendor in $xml.Vendors.Vendor| Where-Object {$_.Type -match "Send"}) {
$NodeExists = $vendor.SelectSingleNode($vendor.EncKey)
if ($NodeExists -ne $null) {
# Do something
}
else {
# something else
}
}
Toute aide serait grandement appréciée.
EDIT: Voici XML de mon fichier de test. J'ai besoin de découvrir EncKey existe ou note pour chaque fournisseur.
<?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>
Il semble que j'utilisais la mauvaise syntaxe pour SelectSingleNode. Voici un exemple de travail.
[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 null
EncKey is not null
Merci à tous pour votre aide.
La façon la plus simple à laquelle je peux penser est d'essayer d'écrire la valeur du nœud dans une variable, puis de voir si cette variable est nulle. Voici un exemple avec le fichier xml de librairie standard.
[xml]$bookstore = Get-Content .\bookstore.xml
foreach ($book in $bookstore.bookstore.book | Where-Object {$_.Type -match "novel"}) {
$NodeExists = $book.author
if($NodeExists){
Write-Host $book.author
}
else{
Write-Host 'No Author'
}
}
Donc pour votre script, je pense que ça pourrait être
$NodeExists = $null
foreach ($vendor in $xml.Vendors.Vendor| Where-Object {$_.Type -match "Send"}) {
$NodeExists = $vendor.EncKey
if ($NodeExists) {
# Do something
}
else {
# something else
}
}
Utilisez XPath pour sélectionner les nœuds correspondants. InnerText est consultable par text()
. Vous pouvez utiliser where-object
, ou ?
aussi; le comportement est un peu différent. Sans exemple de XML, il est difficile d'être plus précis. Utilisez XPath comme ça,
[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.Count
1
$node2.Count
0
# 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 $null
False
$node2 -eq $null
True
À condition de charger l'objet $ xml en tant que XmlDocument à l'aide
$xml = new-object System.Xml.XmlDocument
$xml.LoadXml( (get-content $pathToXmlFile) )
Ensuite, vous pouvez le faire, ce qui est beaucoup plus simple:
if ($vendor.encKey -ne $null) {
# does exist
} else {
# does not exist
}