gabbagundolf
Goto Top

Powershellskript: Löschen eines XML-Elements schlägt fehl

Hallo zusammen,

ich beiße mir gerade an einem Problem die Zähne aus. Vielleicht kann mir hier jemand helfen?

Ich versuche mittels Powershell zwei XML-Dateien miteinander zu vergleichen und in einer dieser in einem bestimmten Block doppelte Einträge zu entfernen.

Ich finde die doppelten Einträge mit dem Skript korrekt heraus, jedoch schlägt das Löschen dieser Elemente mit folgendem Problem fehl.

ERROR: Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
ERROR: In C:\Temp\localXML_bereinigen.ps1:48 Zeichen:4
ERROR: + $node = $localxml:Landscape.SelectSingleNode("/Services[@ ...
ERROR: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ERROR: + CategoryInfo : InvalidOperation: (face-smile [], RuntimeException
ERROR: + FullyQualifiedErrorId : InvokeMethodOnNull

Also ist scheinbar die XPath-Abfrage falsch und liefert kein Ergebnis, aber woran liegts?

Hier die beiden zu vergleichenden Beispiel-XML-Dateien:

globalTest.xml
<?xml version="1.0" encoding="UTF-8"?>  
<Landscape updated="2020-01-14T07:42:53Z" version="1" generator="KP">  
	<Services>
		<Service type="Test" uuid="123" name="Name 1" systemid="ABC"/>  
		<Service type="Test" uuid="456" name="Name 2" systemid="DEF"/>  
		<Service type="Test" uuid="789" name="Name 3" systemid="GHI"/>  
	</Services>
</Landscape>


localTest.xml
<?xml version="1.0" encoding="UTF-8"?>  
<Landscape updated="2020-01-14T07:42:53Z" version="1" generator="KP">  
	<Services>
		<Service type="Test" uuid="123" name="Name 1" systemid="ABC"/>  
		<Service type="Test" uuid="456" name="Name 2" systemid="DEF"/>  
		<Service type="Test" uuid="101" name="Name 2" systemid="JKL"/>  
		<Service type="Test" uuid="789" name="Name 3" systemid="GHI"/>  
	</Services>
</Landscape>

Ziel wäre folgendes
localTest.xml (aktualisierte Datei)
<?xml version="1.0" encoding="UTF-8"?>  
<Landscape updated="2020-01-14T07:42:53Z" version="1" generator="KP">  
	<Services>
		<Service type="Test" uuid="101" name="Name 2" systemid="JKL"/>  
	</Services>
</Landscape>


Hier der Powershellcode:

[xml]$localxml = Get-Content "C:\Temp\localTest.xml"  
[xml]$globalxml = Get-Content "C:\Temp\globalTest.xml"  

$localServices = $localxml.Landscape.Services.Service
$globalServices = $globalxml.Landscape.Services.Service

ForEach ($localService in $localServices)
{
	ForEach ($globalService in $globalServices)
	{
		if ($localService.systemid -like $globalService.systemid) #Wenn systemid identisch
		{
			#Zu löschendes XML-Element anzeigen
			echo "Löschen:"  
			$localService.name
			$localService.systemid
			echo " "  
			
			#XML-Element löschen (Hier scheint der Fehler zu liegen. Habe schon unzählige Versionen getestet. Hier ist eine davon.)
			$node = $localxml:Landscape.SelectSingleNode("/Services[@name='$localService.name']")  
			$node.ParentNode.RemoveChild($node)
		}
	}
}
$localxml.Save($file)

Vielen vielen Dank im Voraus!!!

Gruß GabbaGundolf

Content-Key: 552235

Url: https://administrator.de/contentid/552235

Ausgedruckt am: 19.03.2024 um 11:03 Uhr

Mitglied: 143127
Lösung 143127 28.02.2020 aktualisiert um 10:52:37 Uhr
Goto Top
$node = $localxml:Landscape.SelectSingleNode("/Services[@name='$localService.name']")
Das hat mehrere Fehler und ist übrigens auch überflüssig weil du den Knoten schon über die Variable $localservice vorliegen hast. Erstens der Doppelpunkt hinter der Variablen ist falsch, da kommt ein Punkt hin, und Eigenschaften eines Objekts innerhalb von Anführungszeichen kann man nicht so angeben dazu muss man eine Subexpression nehmen $($localservice.name)

Man kann es sich auch leichter machen und es gleich so wie in diesem Beispiel tun face-smile

https://tio.run/##7dNPT8IwFADws/sUzctM9LCxjSFINkBR/AMiUUyMxpC5vcCSrl22Di ...
Mitglied: GabbaGundolf
GabbaGundolf 28.02.2020 um 11:08:10 Uhr
Goto Top
Hey, vielen vielen Dank für die Lösung!!!

Im Nachhinhein alles logisch, wie du es schreibst. Da war ich ja völlig falsch.
Dein Programmcode hinter dem Link ist genial verkürzt. Ich habe nun mit deinen Hinweisen aber lieber meinen Code angepasst, damit ich den Code selber auch noch in ein paar Wochen verstehe xD

$localService.ParentNode.RemoveChild($localService)
$localxml.Save($filepath)

Vielen vielen Dank Dir!!!

Gruß GabbaGundolf