PowerShell - Suche performantere Lösung für das Verschieben von XML-Nodes
Moin,
ich habe da ein Performanceproblem beim verschieben von XML-Nodes.
Es geht um folgendes:
Ich habe eine XML-Datei. Ca. 3 Millionen Zeilen lang. Der Aufbau ist wie folgt:
Ich muss nun die Elemente aus Ebene 4 auf die Ebene 1 verschieben. Ebene 1 und 2 existieren in der ganzen Datei jeweils nur 4 mal. Aktuell löse ich das so, das ich die entsprechende Node clone, an Ebene 1 "appende" und dann das Ursprungselement lösche. Leider dauert das ewig. Ich kann noch nicht einmal sagen wie lange - nach 15 Minuten breche ich ab. Das ganze muss nämlich in deutlich unter 10 Minuten erledigt sein.
Hat hier evtl. jemand eine Idee, wie ich das Ganze beschleunigen kann?
Gruß Krämer
ich habe da ein Performanceproblem beim verschieben von XML-Nodes.
Es geht um folgendes:
Ich habe eine XML-Datei. Ca. 3 Millionen Zeilen lang. Der Aufbau ist wie folgt:
<EINS>
<ZWEI>
<DREI>
<VIER></VIER>
...zigtausende <VIER></VIER>
</DREI>
<DREI>
<VIER></VIER>
...zigtausende <VIER></VIER>
</DREI>
</ZWEI>
</EINS>
Ich muss nun die Elemente aus Ebene 4 auf die Ebene 1 verschieben. Ebene 1 und 2 existieren in der ganzen Datei jeweils nur 4 mal. Aktuell löse ich das so, das ich die entsprechende Node clone, an Ebene 1 "appende" und dann das Ursprungselement lösche. Leider dauert das ewig. Ich kann noch nicht einmal sagen wie lange - nach 15 Minuten breche ich ab. Das ganze muss nämlich in deutlich unter 10 Minuten erledigt sein.
$doc.SelectNodes('//VIER') | %{
$doc.EINS.AppendChild($_.clone()) | Out-Null
$_.ParentNode.RemoveChild($_) | Out-Null
}
Hat hier evtl. jemand eine Idee, wie ich das Ganze beschleunigen kann?
Gruß Krämer
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 314827
Url: https://administrator.de/contentid/314827
Ausgedruckt am: 04.12.2024 um 08:12 Uhr
9 Kommentare
Neuester Kommentar
Moin,
ich habe nicht viel Ahnung von Powershell und .NET aber aufgrund von Erfahrungen in anderen Bereichen würde ich schrittweise die Komplexität des Befehls auflösen, wenn ein Schritt nicht hilft dann zum nächsten übergehen:
Grüße
Friemler
ich habe nicht viel Ahnung von Powershell und .NET aber aufgrund von Erfahrungen in anderen Bereichen würde ich schrittweise die Komplexität des Befehls auflösen, wenn ein Schritt nicht hilft dann zum nächsten übergehen:
- Statt die Einzelschritte über Pipes miteinander zu verbinden explizit mit Variablen arbeiten.
- Die Einzelbefehle "atomisieren", d.h. die Liste der Vorgänge, die durch einen Einzelbefehl implizit abgearbeitet wird, "von Hand" schreiben.
- Einen anderen XML-Provider verwenden, z.B. ActiveX-Objekte in VBScript. .NET ist zwar sehr schick aber kein nativer Code, da existiert sicherlich Potential für Performance-Steigerung.
Grüße
Friemler
Hi,
you should use an XMLTextReader-Object instead, it parses XML files much faster.
https://msdn.microsoft.com/en-us/library/ff647804.aspx#scalenetchaptch09 ...
Regards
you should use an XMLTextReader-Object instead, it parses XML files much faster.
https://msdn.microsoft.com/en-us/library/ff647804.aspx#scalenetchaptch09 ...
Regards
Hallo Krämer,
für sowas würde ich eher zu XSL-Transformation greifen das geht instant, habe ich hier vor kurzem schon mal gezeigt:
Grüße Uwe
p.s. Erst das Klonen und dann Entfernen ist beim Verschieben überflüssig wenn man stattdessen InserAfter() benutzt, das ist aber ähnlich langsam. Besser du greifst direkt zu XSLT
für sowas würde ich eher zu XSL-Transformation greifen das geht instant, habe ich hier vor kurzem schon mal gezeigt:
Grüße Uwe
p.s. Erst das Klonen und dann Entfernen ist beim Verschieben überflüssig wenn man stattdessen InserAfter() benutzt, das ist aber ähnlich langsam. Besser du greifst direkt zu XSLT
Zitat von @Kraemer:
Verstehe ich das richtig, dass ich einen vorhandenen Node mit InsertAfter auch verschieben kann?
Ja. Wenn man ein vorhandenen Node angibt wird dieser verschoben, ist aber nicht merklich schneller.Verstehe ich das richtig, dass ich einen vorhandenen Node mit InsertAfter auch verschieben kann?
$first = $xml.DocumentElement
$nodes = $xml.SelectNodes('//vier')
foreach($node in $nodes){
[void]$first.InsertAfter($node,$first.LastChild)
}
Ich muss aber noch Sortieren, Filtern etc.
Geht alles auch mit XSL
Kann man machen wenn man immer gleiche XMLs geliefert bekommt und die Verschachtelung gleich bleibt. Ich dachte jetzt eher an unterschiedlich verschachtelte XMLs da du die 'vier'' mit // überall suchst.