HOWTO · PowerShell
Comment analyser des fichiers XML en utilisant PowerShell
Cet article discutera de la façon dont nous pouvons analyser des fichiers XML correctement en utilisant Windows PowerShell.
Sur cette page
Pour extraire des valeurs d’un fichier XML en PowerShell, utilisez Select-Xml avec une expression XPath pour une recherche rapide, System.Xml.XmlDocument pour parcourir un document chargé, ou System.Xml.XmlTextReader pour le lire séquentiellement sous forme de flux. Les exemples ci-dessous lisent uniquement le XML. Ils utilisent un petit inventaire d’ordinateurs et montrent la différence entre le texte d’un élément et la valeur d’un attribut.
Analyser les éléments et les attributs XML avec Select-Xml
Select-Xml évalue une expression XPath et renvoie des objets correspondant aux résultats. Chaque objet expose le nœud XML sélectionné via sa propriété Node. Utilisez InnerText pour lire le texte d’un élément ; InnerXml renvoie le balisage contenu dans l’élément, ce qui est utile lorsque ce contenu doit lui-même être traité comme du XML.
Exécutez cet exemple :
$path = Join-Path ([System.IO.Path]::GetTempPath()) "computers-$([guid]::NewGuid()).xml"
@'
<Computers>
<Computer name="WINPC-01" ip="127.0.0.1"><Name>WINPC-01</Name></Computer>
<Computer name="WINPC-02" ip="192.168.1.105"><Name>WINPC-02</Name></Computer>
</Computers>
'@ | Set-Content -Path $path -Encoding utf8
Write-Output 'Element names:'
Select-Xml -Path $path -XPath '/Computers/Computer/Name' |
ForEach-Object { $_.Node.InnerText }
Write-Output 'Attribute names:'
Select-Xml -Path $path -XPath '/Computers/Computer' |
ForEach-Object { $_.Node.GetAttribute('name') }
Remove-Item -Path $path
Element names:
WINPC-01
WINPC-02
Attribute names:
WINPC-01
WINPC-02
L’expression XPath /Computers/Computer/Name suit la hiérarchie depuis la racine jusqu’à chaque élément Name. Pour sélectionner des attributs, sélectionnez les éléments Computer, puis lisez l’attribut name de chaque nœud obtenu. Dans la sortie de l’exemple, le groupe intitulé Element names affiche le texte des éléments Name, tandis que celui intitulé Attribute names affiche les valeurs des attributs name des éléments Computer. Ces deux libellés restent en anglais. Adaptez l’expression XPath à la structure de votre XML ; les noms et la casse des éléments doivent correspondre au document. Select-Xml accepte aussi du contenu XML via son paramètre -Content lorsque les données sont déjà dans une chaîne.
Charger et interroger du XML avec System.Xml.XmlDocument
System.Xml.XmlDocument charge le document dans un arbre que vous pouvez parcourir. Cette approche est pratique lorsqu’un script doit effectuer plusieurs requêtes liées ou passer des nœuds parents aux nœuds enfants. En contrepartie, le document est conservé en mémoire ; un lecteur en flux peut donc mieux convenir aux fichiers très volumineux.
Cet exemple charge un fichier XML temporaire, sélectionne chaque ordinateur et vérifie la présence d’un enfant Name avant de le lire. Cette vérification est importante si le schéma XML autorise l’absence de cet élément ; SelectSingleNode() renvoie $null lorsqu’aucun résultat ne correspond.
$path = Join-Path ([System.IO.Path]::GetTempPath()) "computers-$([guid]::NewGuid()).xml"
@'
<Computers>
<Computer><Name>WINPC-01</Name></Computer>
<Computer><Ip>192.168.1.105</Ip></Computer>
</Computers>
'@ | Set-Content -Path $path -Encoding utf8
$document = [System.Xml.XmlDocument]::new()
$document.Load($path)
foreach ($computer in $document.SelectNodes('/Computers/Computer')) {
$nameNode = $computer.SelectSingleNode('Name')
if ($null -ne $nameNode) {
Write-Output $nameNode.InnerText
}
else {
Write-Output 'No Name element'
}
}
Remove-Item -Path $path
Utilisez InnerText pour obtenir la valeur textuelle plutôt que InnerXml, qui renvoie le balisage imbriqué dans l’élément. Si le document possède un espace de noms XML par défaut, les expressions XPath sans préfixe risquent de ne pas trouver ses éléments ; créez un XmlNamespaceManager et utilisez un préfixe dans la requête.
Lire du XML sous forme de flux avec System.Xml.XmlTextReader
System.Xml.XmlTextReader expose les nœuds XML dans l’ordre du document au moyen d’un lecteur en lecture seule et à parcours uniquement vers l’avant. Il évite de construire l’arbre complet du document, ce qui peut réduire l’utilisation de la mémoire pour les entrées volumineuses. Comme il ne permet pas de revenir en arrière, extrayez chaque valeur lorsque le lecteur atteint le nœud correspondant. Fermez-le dans un bloc finally afin de libérer le fichier même si le traitement s’interrompt prématurément.
L’exemple suivant lit l’attribut name de chaque balise ouvrante Computer. Il crée son propre fichier XML et libère le lecteur après le traitement.
$path = Join-Path ([System.IO.Path]::GetTempPath()) "computers-$([guid]::NewGuid()).xml"
@'
<Computers>
<Computer name="WINPC-01" ip="127.0.0.1" />
<Computer name="WINPC-02" ip="192.168.1.105" />
</Computers>
'@ | Set-Content -Path $path -Encoding utf8
$reader = [System.Xml.XmlTextReader]::new($path)
try {
while ($reader.Read()) {
if ($reader.NodeType -eq [System.Xml.XmlNodeType]::Element -and
$reader.Name -eq 'Computer') {
Write-Output $reader.GetAttribute('name')
}
}
}
finally {
$reader.Dispose()
Remove-Item -Path $path
}
Pour lire le texte d’un élément plutôt qu’un attribut, vérifiez le nom de l’élément correspondant et lisez son texte lorsque le lecteur se trouve dessus. ReadString() lit le contenu textuel et fait avancer le lecteur ; dans une boucle plus complexe, tenez compte de ce déplacement. Libérez le lecteur lorsque vous avez terminé : s’il reste ouvert, le fichier d’entrée peut rester verrouillé.
Choisir une méthode d’analyse XML en PowerShell
Choisissez Select-Xml lorsqu’une courte requête XPath est le moyen le plus clair d’extraire quelques nœuds d’un fichier ou d’une chaîne. Choisissez System.Xml.XmlDocument si vous avez besoin de parcourir facilement l’arbre, d’effectuer plusieurs requêtes ou d’accéder à des nœuds liés. Choisissez System.Xml.XmlTextReader si vous pouvez traiter les nœuds dans l’ordre et souhaitez éviter de charger tout l’arbre en mémoire.
Les trois méthodes permettent de lire des éléments et des attributs. Elles se distinguent surtout par la manière dont elles donnent accès au document : Select-Xml renvoie les résultats XPath, XmlDocument permet de parcourir un arbre chargé et XmlTextReader avance dans un flux. Choisissez la méthode adaptée à la taille du document et au type de requêtes, puis vérifiez la présence des nœuds ou attributs facultatifs lorsque l’entrée peut les omettre.