Benutzer mit den meisten Antworten
XML Dateien bearbeiten

Frage
-
Halllo @ All,
ich versuche eine XML Datei zu bearbeiten via Power Shell, aber ich bekomm das irgendwie nicht hin.
<?xml version="1.0" encoding="Windows-1252"?> <UserNotifications> <Install lang="de-DE" colorscheme="blue" icon="Blueshield" showtrayicon="true"> <Caption>Aktualisierung</Caption> <Instruction>Beenden Sie ZZZ, um die Aktualisierung zu starten.</Instruction> <Description>Für die Aktualisierung ist das Schließen von ZZZ erforderlich. Stellen Sie sicher, dass Sie alle Daten gespeichert haben.</Description> <RemindLater>Später erinnern:</RemindLater> <RemindLaterButton>Später durchführen</RemindLaterButton> <ActionButton>Installation starten</ActionButton> <SkipText>Sind Sie sicher, dass Sie die Installation abbrechen wollen?</SkipText> <AutoCloseText>Start in: {0} Min, {1} Sek.</AutoCloseText> <ProcessClose>XXX</ProcessClose> </Install> <Install lang="en-US" colorscheme="blue" icon="Blueshield" showtrayicon="true"> <Caption>Software Update</Caption> <Instruction>Close ZZZ in order to start the update</Instruction> <Description>To start the update it is necessary to close ZZZ. Please assure that all data has been saved, if needed.</Description> <RemindLater>Remind me in:</RemindLater> <RemindLaterButton>Postpone</RemindLaterButton> <ActionButton>Install now</ActionButton> <SkipText>Are you sure you want to cancel the installation?</SkipText> <AutoCloseText>Starting in: {0} min, {1} sec</AutoCloseText> <ProcessClose>XXX</ProcessClose> </Install> <Uninstall lang="de-DE" colorscheme="blue" icon="Blueshield" showtrayicon="true"> <Caption>Software-Aktualisierung</Caption> <Instruction>Beenden Sie ZZZ, um die Deinstallation zu starten.</Instruction> <Description>Für die Deinstallation ist das Schließen von ZZZ erforderlich. Stellen Sie sicher, dass Sie alle Daten gespeichert haben.</Description> <RemindLater>Später erinnern:</RemindLater> <RemindLaterButton>Später durchführen</RemindLaterButton> <ActionButton>Deinstallation starten</ActionButton> <SkipText>Sind Sie sicher, dass Sie die Installation abbrechen wollen?</SkipText> <AutoCloseText>Start in: {0} Min, {1} Sek.</AutoCloseText> <ProcessClose>XXX</ProcessClose> </Uninstall> </UserNotifications>
Ich möchte gerne alle Einträge ändern von ZZZ nach z.B. Firefox.
Des Weiteren möchte ich gerne das alle XXX Einträge geändert werden und wenn mehrere Prozesse beendet werden sollen, dann muss noch einen Zeile Hinzugefügt werden.
<ProcessClose>Firefox</ProcessClose>
<ProcessClose>Office</ProcessClose>
<ProcessClose>Notepad</ProcessClose>
Könnte mir da evtl. jemand helfen?
Gruß
Markus
Antworten
-
Hallo,
Das ersetzten der XXX in ProcessClose könntest du mit:
[xml]$xmlfile = Get-Content 'File.xml' $xmlfile.Usernotifications.Install|% {if ($_.ProcessClose -eq 'XXX'){$_.ProcessClose = 'XYZ'}}
erledigen.
Das einfügen von neuen ProcessClose Eigenschaften würde ich auch über xml erledigen. Am besten mit clone und dann Append:
$clone = (($xmlfile.UserNotifications.Install.ChildNodes|? `#text -eq 'XXX')[0]).Clone() $clone.'#text' = 'ABC' $xmlfile.UserNotifications.Install[0].AppendChild($clone)
Das ersetzen von ZZZ würde ich auch über replace lösen. Replace sollte eigentlich in Powershell 3 verfügbar sein. Laut about_Comparison_Operators seit Powershell 2. Probiere es doch mal mit -replace statt .replace. Würde mich interessieren, ob das bei dir einen Unterschied macht.
MfG Jan-Henrik
- Bearbeitet Jan-Henrik DamaschkeMVP Mittwoch, 2. März 2016 09:54
- Als Antwort vorgeschlagen Jan-Henrik DamaschkeMVP Mittwoch, 2. März 2016 13:32
- Nicht als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Mittwoch, 2. März 2016 21:45
- Als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Samstag, 5. März 2016 15:04
- Als Antwort markiert Denniver ReiningMVP, Moderator Dienstag, 8. März 2016 11:35
-
Hallo,
Hab es jetzt hinbekommen.
$Prozesse = "" $Ausgabe = "" $CurrentXMLFile = 'C:\File.xml' [xml]$xmlfile = Get-Content ($CurrentXMLFile) $delnodes = $xmlfile.SelectSingleNode("//UserNotifications/Install[@lang='de-DE']/ProcessClose") $delnodes | %{ $_.parentnode.removechild($_) } $delnodes = $xmlfile.SelectSingleNode("//UserNotifications/Install[@lang='en-US']/ProcessClose") $delnodes | %{ $_.parentnode.removechild($_) } $delnodes = $xmlfile.SelectSingleNode("//UserNotifications/Uninstall[@lang='de-DE']/ProcessClose") $delnodes | %{ $_.parentnode.removechild($_) } $delnodes = $xmlfile.SelectSingleNode("//UserNotifications/Uninstall[@lang='en-US']/ProcessClose") $delnodes | %{ $_.parentnode.removechild($_) } $Prozesse="Winword.exe,Notepad.exe,Firefox.exe" $Ausgabe=$Prozesse -split "," foreach ($i in $Ausgabe){ $xmlNode = $xmlfile.SelectSingleNode("UserNotifications/Install[@lang='de-DE']") $newXmlChild = $xmlNode.AppendChild($xmlfile.CreateElement("ProcessClose")) $newXmlChildText = $newXmlChild.AppendChild($xmlfile.CreateTextNode("$i")) $xmlNode = $xmlfile.SelectSingleNode("UserNotifications/Install[@lang='en-US']") $newXmlChild = $xmlNode.AppendChild($xmlfile.CreateElement("ProcessClose")) $newXmlChildText = $newXmlChild.AppendChild($xmlfile.CreateTextNode("$i")) $xmlNode = $xmlfile.SelectSingleNode("UserNotifications/Uninstall[@lang='de-DE']") $newXmlChild = $xmlNode.AppendChild($xmlfile.CreateElement("ProcessClose")) $newXmlChildText = $newXmlChild.AppendChild($xmlfile.CreateTextNode("$i")) $xmlNode = $xmlfile.SelectSingleNode("UserNotifications/Uninstall[@lang='en-US']") $newXmlChild = $xmlNode.AppendChild($xmlfile.CreateElement("ProcessClose")) $newXmlChildText = $newXmlChild.AppendChild($xmlfile.CreateTextNode("$i")) } $xmlfile.Save($CurrentXMLFile
Vielleicht kann man das noch besser umsetzten, da ich aber noch ein newbie bin in PS, hab ich das nicht besser hinbekommen.
Hallo Jan,
Danke nochmal für die Unterstützung, da es ein teil der Lösung war.
Gruss
MarkusPS. Vielleicht kann mir ja mal jemand das hier erklären, dies ist sehr nervig, ob wohl hier mehr als 4 Zeichen und weniger als 60.000 Zeichen sind. Daher istd er Text jetzt kurz gefasst vorher waren es knapp 3000 Zeichen mit Code.
- Als Antwort markiert Denniver ReiningMVP, Moderator Dienstag, 8. März 2016 11:38
Alle Antworten
-
das erste habe ich ich:
$xmlfile = "C:\TMP\TEST.XML" $xmlDoc = [xml](Get-Content -Path $xmlfile) #XML Einlesen $xmlNode = $xmlDoc.SelectSingleNode("UserNotifications/Install[@lang='de-DE']/Instruction") $xmlNode.InnerText = "Beenden Sie Software1, um die Aktualisierung zu starten." $xmlDoc.Save($xmlfile) #XML Speichern
Ich hatte auch versucht dies so zu lösen
$xmlfile = "C:\TMP\TEST.XML" $temp = Get-Content $xmlfile $temp.replace("ZZZ","Software1") | out-file $xmlfile -force
Leider bekomm ich da ein Fehlermeldung
[System.Object[]] keine Methode mit dem Namen "replace" enthält.
Kann es sein das es unter PS 4.0 geht?
Auf jedenfall geht der erste schritt. Mag vielleicht umständlich sein, aber es geht.
Nun muss ich noch das mit dem Prozessen hinbekommen.
- Bearbeitet mku72 Mittwoch, 2. März 2016 08:26
-
Hallo,
Das ersetzten der XXX in ProcessClose könntest du mit:
[xml]$xmlfile = Get-Content 'File.xml' $xmlfile.Usernotifications.Install|% {if ($_.ProcessClose -eq 'XXX'){$_.ProcessClose = 'XYZ'}}
erledigen.
Das einfügen von neuen ProcessClose Eigenschaften würde ich auch über xml erledigen. Am besten mit clone und dann Append:
$clone = (($xmlfile.UserNotifications.Install.ChildNodes|? `#text -eq 'XXX')[0]).Clone() $clone.'#text' = 'ABC' $xmlfile.UserNotifications.Install[0].AppendChild($clone)
Das ersetzen von ZZZ würde ich auch über replace lösen. Replace sollte eigentlich in Powershell 3 verfügbar sein. Laut about_Comparison_Operators seit Powershell 2. Probiere es doch mal mit -replace statt .replace. Würde mich interessieren, ob das bei dir einen Unterschied macht.
MfG Jan-Henrik
- Bearbeitet Jan-Henrik DamaschkeMVP Mittwoch, 2. März 2016 09:54
- Als Antwort vorgeschlagen Jan-Henrik DamaschkeMVP Mittwoch, 2. März 2016 13:32
- Nicht als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Mittwoch, 2. März 2016 21:45
- Als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Samstag, 5. März 2016 15:04
- Als Antwort markiert Denniver ReiningMVP, Moderator Dienstag, 8. März 2016 11:35
-
Hallo Jan-Henrik,
danke für die Antwort.
das mit dem -replace geht nun, ist auch viel besser somit ist das script bzw. Formular um 130 zeilen kürzer :-) :-O
das erste mit dem ProcessClose
[xml]$xmlfile = Get-Content 'File.xml' $xmlfile.Usernotifications.Install|% {if ($_.ProcessClose -eq 'XXX'){$_.ProcessClose = 'XYZ'}}
Funktioniert auch super :-).
Nur das mit dem zweiten geht noch nicht, da ich noch ein newbie bin in PS, finde ich da nicht den Fehler.
Mir fällt nur auf das nach dem Fragezeichen "`#text" steht damit ist doch hinter dem # alles dokumentiert.
Wenn ich nun die # rausnehmen dann meckert er das die #Text-Eigenschaft nicht findet, was ich auch irgendwie verstehe.
Könntest Du mir nicht nochmal auf die Sprünge helfen?Trotzdem schonmal viele tausend dank.
Markus
-
Hallo Markus,
Das ist ein Fehler vom Highlighting hier im Forum. Powershell erkennt beim erstellen der des XML Objektes ($xmlfile) den Typ der ChildNodes als '#text'. Deswegen hatte ich die Raute mittels "`" escaped. Du kannst die Eigenschaft einsehen, indem du
$xmlfile.UserNotifications.Install.ChildNodes
eingibst. Dann sollte ganz oben der Spaltenname "#text" lauten. Falls diese Spalte bei dir anders heißt, musst du das entsprechend anpassen. Zur Übersichtlichkeit kanst du die Zeile auch so anpassen, dann ist die Eigenschaft in Anführungsstrichen.
($xmlfile.UserNotifications.Install.ChildNodes|? '#text' -eq 'XYZ')
MfG Jan-Henrik
- Bearbeitet Jan-Henrik DamaschkeMVP Mittwoch, 2. März 2016 11:26
-
Hallo Jan,
okay, so halbwegs verstanden, nachdem ich einige Seiten durchgelesen habe.
Nur leider, wenn ich
$xmlfile.UserNotifications.Install.ChildNodes
aufrufe kommt nichts.
Habe die mal mit einer anderen XML Datei versucht wo völlig was andere drin steht, da geht es das er mir die Eigenschaften anzeigt.
Das Problem hatte ich irgendwie schon bei der ZZZ variante, daher hatte ich dann später
$xmlNode = $xmlDoc.SelectSingleNode("UserNotifications/Install[@lang='de-DE']/Instruction")
aufgerufen, da ich nicht anders an die Informationen rankam.
Warum das so ist weiß ich leider nicht.
Hast Du ggf. eine Idee, woran das liegen könnte?
Gruß
Markus- Bearbeitet mku72 Mittwoch, 2. März 2016 13:51
-
Hi Markus,
Wenn du
[xml]$xmlfile = Get-Content C:\XXX\File.xml $xmlfile.UserNotifications.Install.ChildNodes
alleine mit exakt der XML Datei aus deinem ersten Post ausführst, musst du irgendeinen Output bekommen. Prüfe sonst bitte einmal den Pfad und ob überhaupt etwas in der Variable $xmlfile steht. Wenn du nur $xmlfile ausgibst und dann nicht etwas auftaucht, was ähnlich dem hier ist
$xmlfile xml UserNotifications --- ----------------- version="1.0" encoding="Windows-1252" UserNotifications
ist beim einlesen etwas schief gelaufen. dann bitte einmal die Berechtigungen auf die Datei prüfen.
MfG Jan-Henrik
-
Markus, wenn dein Problem gelöst ist, markiere bitte noch Jans Antwort "als Antwort".
Blog: http://bytecookie.wordpress.com
Kostenloser Powershell Snippet Manager v4: Link ! Neue Version !
(Schneller, besser + komfortabler scripten.)
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort. -
Guten Morgen Jan,
Nochmals, vielen Dank für die Hilfe.
Also ich habe das nochmal getestet, leider geht das nicht.
[xml]$xmlfile = Get-Content C:\XXX\File.xml $xmlfile.UserNotifications.Install.ChildNodes
Wenn ich, aber
$xmlfile.UserNotifications.Install
Dann bekomme ich div. Informationen, aus dem XML File.
lang : de-DE colorscheme : blue icon : Blueshield showtrayicon : true Caption : Aktualisierung Instruction : Beenden Sie ZZZ, um die Aktualisierung zu starten. Description : Für die Aktualisierung ist das Schließen von ZZZ erforderlich. Stellen Sie sicher, dass Sie alle Daten gespeichert haben. RemindLater : Später erinnern: RemindLaterButton : Später durchführen ActionButton : Installation starten SkipText : Sind Sie sicher, dass Sie die Installation abbrechen wollen? AutoCloseText : Start in: {0} Min, {1} Sek. ProcessClose : XXX lang : en-US colorscheme : blue icon : Blueshield showtrayicon : true Caption : Software Update Instruction : Close ZZZ in order to start the update Description : To start the update it is necessary to close ZZZ. Please assure that all data has been saved, if needed. RemindLater : Remind me in: RemindLaterButton : Postpone ActionButton : Install now SkipText : Are you sure you want to cancel the installation? AutoCloseText : Starting in: {0} min, {1} sec ProcessClose : XXX
gebe ich dann die Variable ein
$xmlfile xml UserNotifications --- ----------------- version="1.0" encoding="Windows-1252" UserNotifications
Bekomme ich auch das was Du mir da vorgibst.
Gruß
Markus
-
Hallo,
Hab es jetzt hinbekommen.
$Prozesse = "" $Ausgabe = "" $CurrentXMLFile = 'C:\File.xml' [xml]$xmlfile = Get-Content ($CurrentXMLFile) $delnodes = $xmlfile.SelectSingleNode("//UserNotifications/Install[@lang='de-DE']/ProcessClose") $delnodes | %{ $_.parentnode.removechild($_) } $delnodes = $xmlfile.SelectSingleNode("//UserNotifications/Install[@lang='en-US']/ProcessClose") $delnodes | %{ $_.parentnode.removechild($_) } $delnodes = $xmlfile.SelectSingleNode("//UserNotifications/Uninstall[@lang='de-DE']/ProcessClose") $delnodes | %{ $_.parentnode.removechild($_) } $delnodes = $xmlfile.SelectSingleNode("//UserNotifications/Uninstall[@lang='en-US']/ProcessClose") $delnodes | %{ $_.parentnode.removechild($_) } $Prozesse="Winword.exe,Notepad.exe,Firefox.exe" $Ausgabe=$Prozesse -split "," foreach ($i in $Ausgabe){ $xmlNode = $xmlfile.SelectSingleNode("UserNotifications/Install[@lang='de-DE']") $newXmlChild = $xmlNode.AppendChild($xmlfile.CreateElement("ProcessClose")) $newXmlChildText = $newXmlChild.AppendChild($xmlfile.CreateTextNode("$i")) $xmlNode = $xmlfile.SelectSingleNode("UserNotifications/Install[@lang='en-US']") $newXmlChild = $xmlNode.AppendChild($xmlfile.CreateElement("ProcessClose")) $newXmlChildText = $newXmlChild.AppendChild($xmlfile.CreateTextNode("$i")) $xmlNode = $xmlfile.SelectSingleNode("UserNotifications/Uninstall[@lang='de-DE']") $newXmlChild = $xmlNode.AppendChild($xmlfile.CreateElement("ProcessClose")) $newXmlChildText = $newXmlChild.AppendChild($xmlfile.CreateTextNode("$i")) $xmlNode = $xmlfile.SelectSingleNode("UserNotifications/Uninstall[@lang='en-US']") $newXmlChild = $xmlNode.AppendChild($xmlfile.CreateElement("ProcessClose")) $newXmlChildText = $newXmlChild.AppendChild($xmlfile.CreateTextNode("$i")) } $xmlfile.Save($CurrentXMLFile
Vielleicht kann man das noch besser umsetzten, da ich aber noch ein newbie bin in PS, hab ich das nicht besser hinbekommen.
Hallo Jan,
Danke nochmal für die Unterstützung, da es ein teil der Lösung war.
Gruss
MarkusPS. Vielleicht kann mir ja mal jemand das hier erklären, dies ist sehr nervig, ob wohl hier mehr als 4 Zeichen und weniger als 60.000 Zeichen sind. Daher istd er Text jetzt kurz gefasst vorher waren es knapp 3000 Zeichen mit Code.
- Als Antwort markiert Denniver ReiningMVP, Moderator Dienstag, 8. März 2016 11:38