Benutzer mit den meisten Antworten
Zeilen in XML zählen und löschen bis auf 1

Frage
-
Hallo liebe Leut'
hab da ein Problem, wo ich einfach nicht mehr weiter komme.
Für viele von Euch mag dies vielleicht Peanuts sein, aber für
für mich als Laie - der dem Englischen auch nicht so mächtig
ist - zur Zeit nicht lösbar.
Auch nach stundenlangen Recherchen im Internet.Also ich habe eine .nfo Datei mit einem XML-Schema.
In dieser Datei möchte ich von einer Art bestimmten Knoten,
"<thumb>" die Anzahl ermitteln und alle löschen bis auf eins.
Dies kann der erste, der letzte oder mitten drin <thumb> sein.
Und diese befinden sich in variablen Dateien.Also die .nfo ist so aufgebaut:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<movie>
<tagline>diese Zeile soll nicht gelöscht werden</tagline>
<thumb>nur eine von diesen Zeilen mit "thumb" soll übrig bleiben</thumb>
<thumb>die Anzahl variert aber</thumb>
<thumb>manchmal stehen hier nur 3</thumb>
<thumb>dann wieder 10 Zeilen</thumb>
<Set>dies darf dann auch nicht gelöscht werden</set>
</movie>
Wenn ich nun mit folgenden Befehl die Zeilen zähle:$path = 'Pfad zur Datei\DiesIstMeine.nfo'
# Laden der Datei in den Zwischenspeicher
$xml = [xml](Get-Content $Path)$xml.movie.thumb.count
bekomme ich zwar die Anzahl gezeigt, aber wie
kann ich dann die nicht benötigten Zeilen löschen?Habt Ihr da eine Idee?
Auf Eure Antworten bin ich sehr gespannt.
Lg
Svensus
Antworten
-
Ja, XML mit Powershell ist wirklich kein Spaß und leider wenig intuitiv. Ich habs schon hundertmal gemacht und muß jedesmal wieder rumprobieren...
Jedenfalls, gehen tut es folgendermassen (Erklärungen im Code): :)
$filename = "D:\tmp\test.xml" $filenameNew = "D:\tmp\test_Edited.xml" $xml = [xml](Get-Content $filename) # Inhalt des Knotes der erhalten bleiben soll $keepThis = "manchmal stehen hier nur 3" # Alle knoten mit dem namen "thumb" unterhalb "movie" mit XPath auswählen $ThumbNodes = $xml.movie.SelectNodes("./thumb") $ThumbNodes | ForEach-Object { # alle Knoten die den Text in $keepthis nicht enhalten, löschen if ($_."#text" -ne $keepThis ) {
# selektierten Knoten entfernen $xml.movie.RemoveChild( $_ ) } } $xml.save($filenameNew)
Je nachdem wie genau du den Inhalt des zu behaltenden Knotens vorhersagen kannst, musst du die Zeile
$_."#text" -ne $keepThis
ggfls anpassen.
XML ist übrigens sehr pingelig was Groß-Und Kleinschreibung betrifft. Das hier:
<Set>dies darf dann auch nicht gelöscht werden</set>
...gibt schon einen Fehler.
Wenn du dich grundsätzlich etwas einarbeiten willst, lohnt es sich z.b. mal ein Xpath-Tutorial zu googeln.
Grüße, Denniver
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.
- Bearbeitet Denniver ReiningMVP, Moderator Mittwoch, 24. Februar 2016 14:57
- Als Antwort markiert Svensus Samstag, 27. Februar 2016 12:57
-
Es geht (fast) alles. :) Ich habe mal angenommen, das es nicht egal ist, welche Zeile stehen bleibt. Wenn das aber so ist, dann geht auch das.
So bleibt immer nur der erste thumb-Knoten übrig unabhängig von Inhalt und Anzahl:
$filename = "D:\tmp\test.xml" $filenameNew = "D:\tmp\test_Edited.xml" $xml = [xml](Get-Content $filename) $ThumbNodes = $xml.movie.SelectNodes("./thumb") if ($ThumbNodes.Count -gt 1) { $ThumbNodes | Select-Object -Index (1..($ThumbNodes.Count -1)) | ForEach-Object { $xml.movie.RemoveChild( $_ ) } $xml.save($filenameNew) }
Grüße, Denniver
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.- Bearbeitet Denniver ReiningMVP, Moderator Donnerstag, 25. Februar 2016 12:23
- Als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Freitag, 26. Februar 2016 18:52
- Als Antwort markiert Svensus Samstag, 27. Februar 2016 12:56
-
Hallo Denniver,
Du hast Recht.
Ich fasse noch einmal zusammen, für alle die sich für mein Problem interessieren.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<movie>
<data>Problem 1</data>
<thumb>Hier soll nur eine Zeile uebrig bleiben</thumb>
<thumb>Ich soll weg</thumb>
<thumb>Und ich auch. Die Anzahl an Zeile ist unbekannt</thumb>
<thumb>Ich muss auch weg</thumb>
<data>Problem 2</data>
<fanart>
<thumb>Auch hier soll eine Zeile uebrig bleiben.</thumb>
<thumb>Ich soll weg</thumb>
<thumb>Und ich auch. Die Anzahl an Zeile ist unbekannt</thumb>
</fanart>
<data>Problem 3</data><set>
<order>0</order>
<thumb>Aber ich muss bleiben</thumb>
</set>
<set>
<order>1</order>
<thumb>Und ich auch. Und alle, die nach mir kommen.</thumb>
</set>
</movie>Ich habe hier verschiedene Knoten (ich nenne diese aus Unkenntnis mal so), die alle mit "thumb" zu tun haben.
Problem 1 soll alle gelöscht werden bis auf 1 Zeile.
Problem 2 soll innerhalb von fanart auch alle thumb löschen bis 1 Zeile.
Problem 3 ist keines, es soll bei der Lösung nur beachtet werden.
Die folgende Lösung habe ich von Denniver zusammengeführt und hoffe es kann dem einen oder anderem helfen:
$filename = "C:Test.nfo" $filenameNew = "C:Test_Edit.nfo" $xml = [xml](Get-Content $filename) ########################################################################################################## # Loesung zu Problem 1 $ThumbNodes = $xml.movie.SelectNodes("./thumb") if ($ThumbNodes.Count -gt 1) { $ThumbNodes | Select-Object -Index (1..($ThumbNodes.Count -1)) | ForEach-Object { $xml.movie.RemoveChild( $_ ) } $xml.save($filenameNew) } ########################################################################################################## # Loesung zu Problem 2 $fanart = $xml.movie.fanart $thumbnodes = $fanart.SelectNodes("./thumb") if ($thumbnodes.Count -gt 1) { $thumbnodes | Select-Object -Index (1..($thumbnodes.Count -1)) | ForEach-Object { $fanart.RemoveChild( $_ ) } $xml.save($filenameNew) }
LG
Svensus
- Als Antwort markiert Svensus Samstag, 27. Februar 2016 12:56
Alle Antworten
-
Ja, XML mit Powershell ist wirklich kein Spaß und leider wenig intuitiv. Ich habs schon hundertmal gemacht und muß jedesmal wieder rumprobieren...
Jedenfalls, gehen tut es folgendermassen (Erklärungen im Code): :)
$filename = "D:\tmp\test.xml" $filenameNew = "D:\tmp\test_Edited.xml" $xml = [xml](Get-Content $filename) # Inhalt des Knotes der erhalten bleiben soll $keepThis = "manchmal stehen hier nur 3" # Alle knoten mit dem namen "thumb" unterhalb "movie" mit XPath auswählen $ThumbNodes = $xml.movie.SelectNodes("./thumb") $ThumbNodes | ForEach-Object { # alle Knoten die den Text in $keepthis nicht enhalten, löschen if ($_."#text" -ne $keepThis ) {
# selektierten Knoten entfernen $xml.movie.RemoveChild( $_ ) } } $xml.save($filenameNew)
Je nachdem wie genau du den Inhalt des zu behaltenden Knotens vorhersagen kannst, musst du die Zeile
$_."#text" -ne $keepThis
ggfls anpassen.
XML ist übrigens sehr pingelig was Groß-Und Kleinschreibung betrifft. Das hier:
<Set>dies darf dann auch nicht gelöscht werden</set>
...gibt schon einen Fehler.
Wenn du dich grundsätzlich etwas einarbeiten willst, lohnt es sich z.b. mal ein Xpath-Tutorial zu googeln.
Grüße, Denniver
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.
- Bearbeitet Denniver ReiningMVP, Moderator Mittwoch, 24. Februar 2016 14:57
- Als Antwort markiert Svensus Samstag, 27. Februar 2016 12:57
-
Hallo Denniver,
vielen Dank für die schnelle Antwort.
Deine Lösung ist sehr gut.
Trotzdem habe ich dazu noch eine weitere Frage. Bei Deiner Lösung muss ich ja wieder diese Datei in die Hand nehmen und
$_."#text" -ne $keepThis
hier was eingeben, damit die Datei verarbeitet wird.
Kann es nicht gemacht werden, dass PS die Datei einfach einliest, die Zeilen sich ansieht und dann alle Zeilen mit <thumb>Egal was</thumb> löscht bis auf eine einzige?
LG
Svensus
-
Es geht (fast) alles. :) Ich habe mal angenommen, das es nicht egal ist, welche Zeile stehen bleibt. Wenn das aber so ist, dann geht auch das.
So bleibt immer nur der erste thumb-Knoten übrig unabhängig von Inhalt und Anzahl:
$filename = "D:\tmp\test.xml" $filenameNew = "D:\tmp\test_Edited.xml" $xml = [xml](Get-Content $filename) $ThumbNodes = $xml.movie.SelectNodes("./thumb") if ($ThumbNodes.Count -gt 1) { $ThumbNodes | Select-Object -Index (1..($ThumbNodes.Count -1)) | ForEach-Object { $xml.movie.RemoveChild( $_ ) } $xml.save($filenameNew) }
Grüße, Denniver
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.- Bearbeitet Denniver ReiningMVP, Moderator Donnerstag, 25. Februar 2016 12:23
- Als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Freitag, 26. Februar 2016 18:52
- Als Antwort markiert Svensus Samstag, 27. Februar 2016 12:56
-
Hallo Denniver und liebe Community,
der letzte Befehl, ist genau nach meinem Geschmack. Aber wie das Leben so spielt, habe ich wohl die Rechnung ohne der Wirt gemacht. Denn die .nfo Datei hat da noch ein kleine Falle gebaut.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<movie>
<thumb>Ich bin schon bearbeitet worden und muss sitzen bleiben.</thumb>
<fanart>
<thumb>Und ich darf auch nicht entfernt werden.</thumb>
<thumb>Ich muss hier verschwinden.</thumb>
<thumb>Ich auch.</thumb>
<thumb>Und ich erst recht. Und alle folgenden Brueder auch.</thumb>
</fanart>
<set>
<order>0</order>
<thumb>Halt! Ich muss auf alle Faelle bleiben.</thumb>
</set>
<set>
<order>1</order>
<thumb>Und ich erst Recht.</thumb>
</set>
</movie>Will ich die thumbs in dem Knoten 'fanart' bis auf eines löschen, mit dem bearbeiteten Befehl von oben.
$filename = "C:\Edit.nfo" $filenameNew = "C:\Edit_New.nfo" $xml = [xml](Get-Content $filename) $fanart = $xml.movie.fanart $thumbnodes = $fanart.SelectNodes("./thumb") if ($thumbnodes.Count -gt 1) { $thumbnodes | Select-Object -Index (1..($thumbnodes.Count -1)) | ForEach-Object { $fanart.RemoveChild( $_ ) } $xml.save($filename) }
passiert überhaupt nichts. Und wenn ich am Ende vor ".RemoveChild" die Variable auf folgendes ändere:
"$thumbnodes.RemoveChild.....", spuckt PS mir eine Fehlermeldung aus:
"....."Der zu entfernende Knoten ist diesem Knoten nicht untergeordnet.".....".
Könnt Ihr mir da noch einmal helfen?
Wünsche allen ein schönes WE.
LG
Svensus
-
$xml.save($filename)
ist falsch. Du speicherst deinen Edit in das Original anstatt in die "_New".
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.- Als Antwort markiert Svensus Samstag, 27. Februar 2016 12:56
- Tag als Antwort aufgehoben Denniver ReiningMVP, Moderator Samstag, 27. Februar 2016 13:50
-
Hallo Denniver,
Du hast Recht.
Ich fasse noch einmal zusammen, für alle die sich für mein Problem interessieren.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<movie>
<data>Problem 1</data>
<thumb>Hier soll nur eine Zeile uebrig bleiben</thumb>
<thumb>Ich soll weg</thumb>
<thumb>Und ich auch. Die Anzahl an Zeile ist unbekannt</thumb>
<thumb>Ich muss auch weg</thumb>
<data>Problem 2</data>
<fanart>
<thumb>Auch hier soll eine Zeile uebrig bleiben.</thumb>
<thumb>Ich soll weg</thumb>
<thumb>Und ich auch. Die Anzahl an Zeile ist unbekannt</thumb>
</fanart>
<data>Problem 3</data><set>
<order>0</order>
<thumb>Aber ich muss bleiben</thumb>
</set>
<set>
<order>1</order>
<thumb>Und ich auch. Und alle, die nach mir kommen.</thumb>
</set>
</movie>Ich habe hier verschiedene Knoten (ich nenne diese aus Unkenntnis mal so), die alle mit "thumb" zu tun haben.
Problem 1 soll alle gelöscht werden bis auf 1 Zeile.
Problem 2 soll innerhalb von fanart auch alle thumb löschen bis 1 Zeile.
Problem 3 ist keines, es soll bei der Lösung nur beachtet werden.
Die folgende Lösung habe ich von Denniver zusammengeführt und hoffe es kann dem einen oder anderem helfen:
$filename = "C:Test.nfo" $filenameNew = "C:Test_Edit.nfo" $xml = [xml](Get-Content $filename) ########################################################################################################## # Loesung zu Problem 1 $ThumbNodes = $xml.movie.SelectNodes("./thumb") if ($ThumbNodes.Count -gt 1) { $ThumbNodes | Select-Object -Index (1..($ThumbNodes.Count -1)) | ForEach-Object { $xml.movie.RemoveChild( $_ ) } $xml.save($filenameNew) } ########################################################################################################## # Loesung zu Problem 2 $fanart = $xml.movie.fanart $thumbnodes = $fanart.SelectNodes("./thumb") if ($thumbnodes.Count -gt 1) { $thumbnodes | Select-Object -Index (1..($thumbnodes.Count -1)) | ForEach-Object { $fanart.RemoveChild( $_ ) } $xml.save($filenameNew) }
LG
Svensus
- Als Antwort markiert Svensus Samstag, 27. Februar 2016 12:56