Benutzer mit den meisten Antworten
Fehler beim Einlesen von XML-Dateien

Frage
-
Hallo zusammen,
ich versuche mehrere XML-Dateien einzulesen und die Ausgabe für bestimmte Spalten Einträge in einer Datei auszugeben.
Hier ein Teil meines Scriptes:
$DebugPreference = "Continue" #Suche nach folgenden Mustern in der Dateibeschreibung $pattern2 = "QServer_64" $pattern3= "QDBODBC_64_" #Pfad des Logfile Ordners: $path = "..." #Suche Inhalt des Pfades $files = ls $path -recurse| Where-Object {$_.Extension -eq '.xml'} $files.gettype(); foreach ($file in $files) { #Abfrage der Muster If($file -match $pattern2) { write-host "Lese Datei $file" [xml] $xmldoc = Get-Content $file.FullName -encoding unknown $finalCSV_QServer += $xmldoc.document.root.logentries.logentry | Where {$_.logkind -like "Error" -or $_.logkind -like "Warning" -or $_.logkind -like "Caution" } } If($file -match $pattern3) { write-host "Lese Datei $file" [xml] $xmldoc2 = Get-Content $file.FullName -encoding unknown $finalQDBODBC += $xmldoc2.root.logentries.logentry | Where {$_.logkind -like "Error" -or $_.logkind -like "Warning" -or $_.logkind -like "Caution" } } } #Speichern der ausgabe in den gleichen Ordner im CSV Format: Write-host "Speichere $path\NEUQ-Server.csv" $finalCSV_QServer | Export-CSV "$path\NEUQ-Server.csv" -NoType -Delimiter ";" -Encoding UTF8 Write-host "Speichere $path\NEUQ-DBODBC.csv" $finalQDBODBC| Export-CSV "$path\NEUQ-DBODBC.csv" -NoType -Delimiter ";" -Encoding UTF8
Mein Script funktioniert für einen Teil der XML-Dateien. Für den anderen Teil bekomme ich folgende Fehlermeldung:
Der Wert "System.Object[]" kann nicht in den Typ "System.Xml.XmlDocument" konvertiert werden. Fehler: "Ungültige Daten auf Stammebene. Zeile 1, Position 1." Bei Zeile:31 Zeichen:22 + [xml] $xmldoc <<<< = Get-Content $file.FullName -encoding unknown + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException + FullyQualifiedErrorId : RuntimeException
Die Struktur der XML-Dateien ist bei allen gleich:<root> <logentries xmlns="log"> <logentry> <index></index> <starttime></starttime> <pid></pid> <threadname></threadname> <threadid></threadid> <logicalname></logicalname> <error></error> <logkind></logkind> </logentry> </logentries> </root>
Aktuell verstehe ich nicht wieso es hier zu einer Fehlermeldung kommt und wie ich diese bereinigen kann.
Kann mir jemand weiterhelfen bei dem Thema?
- Bearbeitet Denniver ReiningMVP, Moderator Mittwoch, 25. Mai 2016 10:36 Kurze Titel bitte!
Antworten
-
> Lese Datei QDBODBC_64_1.xml> Ausnahme beim Aufrufen von "Load" mit 1 Argument(en): "Die Datei "X:\QDBODBC_64_1696_20160511_0002_0.xml" konnte nicht gefunden werden."Wir gehen mal davon aus, daß dieser Code hier die Fehlermeldung produziert:Write-Host "Lese Datei $file"$xmldata2.Load("$file")Hm - warum steht beim Write-Host etwas anderes in $file als dasXML-Objekt dann meldet? Weil Get-ChildItem - anders als Get-Item - alsStandardproperty zwar auch den Namen hat, aber bei Get-ChildItem ist daswirklich nur der Name. Du solltest .FullName verwenden :-)Write-Host "Lese Datei $($file.FullName)"$xmldata2.Load("$($file.FullName)")Zur Verdeutlichung, was ich meine:PS C:\users\public> Write-Host ( Get-ChildItem -Filter "*.txt" )ReadMe.txtPS C:\users\public> Write-Host ( Get-Item "*.txt" )C:\users\public\ReadMe.txtBeides die gleiche Datei, einmal mit LW/Pfad, einmal ohne...Tipp: Bei Get-ChildItem wäre -filter besser als |? - filtern immer links :-)
- Als Antwort markiert Tschenn1 Freitag, 3. Juni 2016 13:21
Alle Antworten
-
Ist bei den betreffenden XML-Dateien die Struktur in Ordnung? Hast du dir die XML-Dateien, wo der Fehler kommt, mal angesehen?
Ich hatte manchmal bei Get-Content das Problem, dass ein Dokument nicht korrekt eingelesen worden ist. Abhilfe hat dann der Schalter "-Raw" gegeben. Du kannst diesen ja mal testen.
-
Überprüf mal, ob die Dateien auch gleich codiert sind.
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. -
Hallo,
aus irgendeinem Grund hat PS Schwierigkeiten mit allen Dateien die "§pattern2" betreffen.
Ich habe die XML-Dateien nun mehrfach auf Unterschiede geprüft und kann hier keine Abweichungen finden.
Habe mir auch neue Dateien angeschaut auch hier nichts das unterscheidet.
Alle Dateien sind vom gleichen Typ:
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True FileInfo System.IO.FileSystemInfo
Ich hatte vergessen zu erwähnen dass ich PS1 verwende und das leider nicht ändern kann. Der Parameter -raw wurde erst mit PS3 eingeführt
führt und funktioniert deshalb nicht.
Ich habe festgestellt dass einige Dateien beispielsweise beim ersten Ausführen nicht gelesen werden, allerdings beim Dritten mal schon und bei 4 mal wieder nicht (und dann eben diese Fehlermeldung kommt) etc...
Kann es sein dass Powershell Probleme hat viele Dateien nacheinander einzulesen?
- Bearbeitet Tschenn1 Mittwoch, 25. Mai 2016 12:28
-
>Kann es sein dass Powershell Probleme hat viele Dateien nacheinander einzulesen
Nein.
Wenn das wirklich so ist, das die selbe Datei (keine gleiche, keine ähnliche. Die selbe.) mal korrekt verarbeitet wird und mal den obigen Fehler auswirft hat das mit Sicherheit nichts mit Powershell zu tun.
Da kann dann eigentlich nur ein Disk/Netzwerk Lesefehler oder ein anderes obskures Problem des verarbeitenden Rechners oder der Windows-Installation der Grund sein. Das kannst du aber einfach überprüfen, in dem du das Script und die Dateien lokal auf einen anderen Rechner kopierst und dort testest.Wenn der Fehler auftritt, würde ich mir mir auch mal $xmldoc ansehen, den Inhalt, den Objekttyp etc. Vielleicht gibt das auch noch einen Hinweis auf die Ursache des Problems.
Blog: http://bytecookie.wordpress.com
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.
-
Hallo,
danke für die Rückmeldung.
Ich habe etwas recherchiert und scheinbar kann es zu Fehlern kommen wenn man den absoluten Pfad der XML-Dateien ändert. Ich hatte die Dateien vorher auf einem anderen Laufwerk und sie dann woanders hin kopiert.
Ich habe einmal alternativ zu get-Content $file", .Load("$file") verwendet. Auch hier bekomme ich (eine alternative) Fehlermeldungen:
Ausnahme beim Aufrufen von "Load" mit 1 Argument(en): "Die Datei "X:\QServer_64.xml" konnte nicht gefunden werden." Bei Zeile:27 Zeichen:14 + $xmldata.Load <<<< ("$file") + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException
PS schreibt dass es die Datei im X-Laufwerk nicht finden kann. Die Datei liegt allerdings gar nicht mehr hier (hier lag sie mal ursprünglich).
Ich denke PS merkt sich hier aus unerklärlichen Gründen den vorherigen Pfad der Datei und nicht den neuen.
Ich weiß noch nicht wie ich das beheben kann.
-
> Ausnahme beim Aufrufen von "Load" mit 1 Argument(en): "Die Datei "X:\QServer_64.xml" konnte nicht gefunden werden."> Ich denke PS merkt sich hier aus unerklärlichen Gründen den vorherigen> Pfad der Datei und nicht den neuen.PS merkt sich eigentlich gar nichts - aber wenn in $file der falschePfad steht :-)Was genau meinst Du mit "hier lag sie mal ursprünglich" - welcheVerweise auf welche Laufwerke/Pfade hast Du wie und wo in Deinem Skriptgespeichert? (Du schrubst oben, daß es nur ein Auszug sei, was wir sehen)
-
> Ich habe etwas recherchiert und scheinbar kann es zu Fehlern kommen wenn man den absoluten Pfad der XML-Dateien ändert.
Was dein "unerklärliches" Pfadproblem betrifft: was benutzt du zum editeren/ausführen des Scriptes? ISE gabs ja noch nicht.
Wenn das wahr ist, muß das ein lange, lange gefixter Bug von Powershell v1 sein. Poste mal einen Link zu dem was du da gefunden hast.
Und was ist mit den anderen Maßnahmen die ich vorgeschlagen habe? Was ist dabei herausgekommen?Blog: http://bytecookie.wordpress.com
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.
-
Hallo,
hier mal das ganze Script:
#LogScript Version 1.0 $CurrentDate = get-date Write-host "Skript zur Konsolidierung der Fehler-Logfiles QServer_64 und QDBODBC_64 )" $DebugPreference = "Continue" #Suche nach folgenden Mustern in der Dateibeschreibung $pattern1 = "QServer_64_" $pattern2= "QDBODBC_64_" #Pfad des Logfile Ordners: $path = "D:\...\LogfilesApp10.05.2016" #Suche Inhalt des Pfades $files = ls $path -recurse| Where-Object {$_.Extension -eq '.xml'} $files.gettype(); foreach ($file in $files) { #Abfrage der Muster If($file -match $pattern1) { write-host "Lese Datei $file" [xml] $xmldoc = Get-Content $file.FullName -encoding UTF8 $finalCSV_QServer += $xmldoc.root.logentries.logentry | Where {$_.logkind -like "Error" -or $_.logkind -like "Warning" -or $_.logkind -like "Caution" } } If($file -match $pattern2) { write-host "Lese Datei $file" [xml] $xmldoc2 = Get-Content $file.FullName -encoding UTF8 $finalQDBODBC += $xmldoc2.root.logentries.logentry | Where {$_.logkind -like "Error" -or $_.logkind -like "Warning" -or $_.logkind -like "Caution" } } } #Speichern der ausgabe in den gleichen Ordner im CSV Format wenn die Variable $finalCSV_QServer $finalQDBODBC bzw. existiert: if($finalCSV_QServer){ Write-host "Speichere $path\NEUQ-Server.csv" $finalCSV_QServer | Export-CSV "$path\NEUQ-Server$((get-date).toString('MM-dd-yyy')).csv" -NoType -Delimiter ";" -Encoding UTF8 } if($finalQDBODBC){ Write-host "Speichere $path\NEUQ-DBODBC.csv" $finalQDBODBC| Export-CSV "$path\NEUQ-DBODBC$((get-date).toString('MM-dd-yyy')).csv" -NoType -Delimiter ";" -Encoding UTF8 } if ($finalCSV_QServer){ remove-variable -Name finalCSV_QServer } if($finalQDBODBC){ remove-variable -Name finalQDBODBC } #QServer zusammenfassung #Pfad der zu ergänzenden Datei $CSVDateiPfad = "$path\allQ_Server.csv" #die hinzuzufügenden Daten $NeueDaten = Import-Csv "$path\NEUQ-Server$((get-date).toString('MM-dd-yyy')).csv" -Delimiter ";" #StreamReader öffnen und Tabellenkopf lesen $Reader = New-Object System.IO.StreamReader($CSVDateiPfad) $Header = $Reader.ReadLine() $AusgabeFelder = $Header -split ";" #StreamReader wieder schließen $Reader.Close() #StreamWriter öffnen $Writer = New-Object System.IO.StreamWriter($CSVDateiPfad, $true) #Daten zeilenweise anfügen foreach($d in $NeueDaten) { #Ausgabezeile formen; Reihenfolge durch $AusgabeFelder sichergestellt $Zeile = ($AusgabeFelder | foreach{$d.$_}) -join ";" $Writer.WriteLine($Zeile) } $Writer.Close() $Cons1 = ( $NeueDaten | sort description -unique) if($Cons1){ write-host "Speichere $path\Q_Server_Consolidated$((get-date).toString('MM-dd-yyy')).csv" $Cons1|Export-CSV "$path\Q_ServerConsolidated$((get-date).toString('MM-dd-yyy')).csv" -NoType -Delimiter ";" -Encoding UTF8 } #QDBCODBC Dateien #Pfad der zu ergänzenden Datei $CSVDateiPfad2 = "$path\allQ_DBODBC.csv" #die hinzuzufügenden Daten $NeueDaten2 = Import-Csv "$path\NEUQ-DBODBC$((get-date).toString('MM-dd-yyy')).csv" -Delimiter ";" #StreamReader öffnen und Tabellenkopf lesen $Reader2 = New-Object System.IO.StreamReader($CSVDateiPfad2) $Header2 = $Reader2.ReadLine() $AusgabeFelder2 = $Header2 -split ";" #StreamReader wieder schließen $Reader2.Close() #StreamWriter öffnen $Writer2 = New-Object System.IO.StreamWriter($CSVDateiPfad2, $true) #Daten zeilenweise anfügen foreach($o in $NeueDaten2) { #Ausgabezeile formen; Reihenfolge durch $AusgabeFelder sichergestellt $Zeile2 = ($AusgabeFelder2 | foreach{$o.$_}) -join ";" $Writer2.WriteLine($Zeile2) } $Writer2.Close() $Cons2 = ( $NeueDaten2 | sort description -unique) if($Cons2){ write-host "Speichere $path\Q_DBODBC_Consolidated$((get-date).toString('MM-dd-yyy')).csv" $Cons2|Export-CSV "$path\Q_DBODBC_Consolidated$((get-date).toString('MM-dd-yyy')).csv" -NoType -Delimiter ";" -Encoding UTF8 }
Mit diesem Script bekomme ich folgende Fehlermeldung:
Lese Datei QServer_64_1.xml Der Wert "System.Object[]" kann nicht in den Typ "System.Xml.XmlDocument" konvertiert werden. Fehler: "Ungültige Daten auf Stammebene. Zeile 1, Position 1." Bei Zeile:32 Zeichen:22 + [xml] $xmldoc <<<< = Get-Content $file.FullName -encoding UTF8 + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException + FullyQualifiedErrorId : RuntimeException
Ich habe das Script eben 2mal durchlaufen lassen und im ersten Durchgang ist diese Fehlermeldung bei 2 von 8 Dateien aufgetreten. Im zweiten Durchgang nur bei einer Datei. Dabei handelt es sich jedes Mal um unterschiedliche Dateien.
Meine Dateien liegen alle auf dem D:Laufwerk.
Alternativ habe ich ein zweites ähnliches Script geschrieben, welches den Inhalt von XML-Dateien mit Load("$file") liest.
Hier mal der Code:
#LogScript Version 1.0 $CurrentDate = get-date Write-host "Skript zur Konsolidierung der Fehler-Logfiles QServer_64 und QDBODBC_64" $DebugPreference = "Continue" #Pfad des Logfile Ordners: $path= "D:\Users\..\LogfilesApp10.05.2016" $files = ls $path -recurse| Where-Object {$_.Extension -eq '.xml'} #Dateibezeichnungen: $pattern1="QServer_64" $pattern2 ="QDBODBC_64" $pattern3 = "QDBODBC_FTGW" foreach($file in $files) { if($file -match $pattern1){ $xmldata = New-Object XML Write-Host "Lese Datei $file" $xmldata.Load("$file") $patternQ += $xmldata.root.logentries.logentry |Where {$_.logkind -like "Error" -or $_.logkind -like "Warning" -or $_.logkind -like "Caution" } } if($file -match $pattern2){ $xmldata2 = New-Object XML Write-Host "Lese Datei $file" $xmldata2.Load("$file") $patternQDBC += $xmldata2.root.logentries.logentry |Where {$_.logkind -like "Error" -or $_.logkind -like "Warning" -or $_.logkind -like "Caution" } } if($file -match $pattern3){ $xmldata3 = New-Object XML Write-Host "Lese Datei $file" $xmldata3.Load("$file") $patternQDBC_FTGW += $xmldata3.root.logentries.logentry |Where {$_.logkind -like "Error" -or $_.logkind -like "Warning" -or $_.logkind -like "Caution" } } } if($patternQ){ $patternQ|Export-CSV "$path\NEUQ_Server$((get-date).toString('MM-dd-yyy')).csv" -noType -Delimiter ";" -Encoding UTF8 } if($patternQDBC){ $patternQDBC|Export-CSV "$path\NEUQ-DBODBC$((get-date).toString('MM-dd-yyy')).csv" -noType -Delimiter ";" -Encoding UTF8 } if($patternQDBC_FTGW){ $patternQDBC_FTGW|Export-CSV "$path\NEU-QDBODBC_FTGW$((get-date).toString('MM-dd-yyy')).csv" -noType -Delimiter ";" -Encoding UTF8 } #Variablen wieder freigeben if ($patternQ){ remove-variable -Name patternQ } if($patternQDBC){ remove-variable -Name patternQDBC } if($patternQDBC_FTGW){ remove-variable -Name patternQDBC_FTGW } #QServer zusammenfassung #Pfad der zu ergänzenden Datei $CSVDateiPfad = "$path\allQ_Server.csv" #die hinzuzufügenden Daten $NeueDaten = Import-Csv "$path\NEUQ_Server$((get-date).toString('MM-dd-yyy')).csv" -Delimiter ";" #StreamReader öffnen und Tabellenkopf lesen $Reader = New-Object System.IO.StreamReader($CSVDateiPfad) $Header = $Reader.ReadLine() $AusgabeFelder = $Header -split ";" #StreamReader wieder schließen $Reader.Close() #StreamWriter öffnen $Writer = New-Object System.IO.StreamWriter($CSVDateiPfad, $true) #Daten zeilenweise anfügen foreach($d in $NeueDaten) { #Ausgabezeile formen; Reihenfolge durch $AusgabeFelder sichergestellt $Zeile = ($AusgabeFelder | foreach{$d.$_}) -join ";" $Writer.WriteLine($Zeile) } $Writer.Close() $Cons1 = ( $NeueDaten | sort description -unique) if($Cons1){ write-host "Speichere $path\Q_Server_Consolidated$((get-date).toString('MM-dd-yyy')).csv" $Cons1|Export-CSV "$path\Q_ServerConsolidated$((get-date).toString('MM-dd-yyy')).csv" -NoType -Delimiter ";" -Encoding UTF8 } #QDBCODBC_64 Dateien #Pfad der zu ergänzenden Datei $CSVDateiPfad2 = "$path\allQ_DBODBC.csv" #die hinzuzufügenden Daten $NeueDaten2 = Import-Csv "$path\NEUQ-DBODBC$((get-date).toString('MM-dd-yyy')).csv" -Delimiter ";" #StreamReader öffnen und Tabellenkopf lesen $Reader2 = New-Object System.IO.StreamReader($CSVDateiPfad2) $Header2 = $Reader2.ReadLine() $AusgabeFelder2 = $Header2 -split ";" #StreamReader wieder schließen $Reader2.Close() #StreamWriter öffnen $Writer2 = New-Object System.IO.StreamWriter($CSVDateiPfad2, $true) #Daten zeilenweise anfügen foreach($o in $NeueDaten2) { #Ausgabezeile formen; Reihenfolge durch $AusgabeFelder sichergestellt $Zeile2 = ($AusgabeFelder2 | foreach{$o.$_}) -join ";" $Writer2.WriteLine($Zeile2) } $Writer2.Close() $Cons2 = ( $NeueDaten2 | sort description -unique) if($Cons2){ write-host "Speichere $path\Q_DBODBC_64_Consolidated$((get-date).toString('MM-dd-yyy')).csv" $Cons2|Export-CSV "$path\Q_DBODBC_64_Consolidated$((get-date).toString('MM-dd-yyy')).csv" -NoType -Delimiter ";" -Encoding UTF8 } #QDBCODBC_FTGW Dateien #Pfad der zu ergänzenden Datei $CSVDateiPfad3 = "$path\allQ_DBODBC_FTGW.csv" #die hinzuzufügenden Daten $NeueDaten3 = Import-Csv "$path\NEU-QDBODBC_FTGW$((get-date).toString('MM-dd-yyy')).csv" -Delimiter ";" #StreamReader öffnen und Tabellenkopf lesen $Reader3 = New-Object System.IO.StreamReader($CSVDateiPfad3) $Header3 = $Reader3.ReadLine() $AusgabeFelder3 = $Header3 -split ";" #StreamReader wieder schließen $Reader3.Close() #StreamWriter öffnen $Writer3 = New-Object System.IO.StreamWriter($CSVDateiPfad3, $true) #Daten zeilenweise anfügen foreach($o in $NeueDaten3) { #Ausgabezeile formen; Reihenfolge durch $AusgabeFelder sichergestellt $Zeile3 = ($AusgabeFelder3 | foreach{$o.$_}) -join ";" $Writer3.WriteLine($Zeile3) } $Writer3.Close() $Cons3 = ( $NeueDaten3 | sort description -unique) if($Cons3){ write-host "Speichere $path\Q_DBODBC_FTGW_Consolidated$((get-date).toString('MM-dd-yyy')).csv" $Cons3|Export-CSV "$path\Q_DBODBC_FTGW_Consolidated$((get-date).toString('MM-dd-yyy')).csv" -NoType -Delimiter ";" -Encoding UTF8 }
Das interessante dabei ist, dass ich hier folgende Fehlermeldung bekomme:
Lese Datei QDBODBC_64_1.xml Ausnahme beim Aufrufen von "Load" mit 1 Argument(en): "Die Datei "X:\QDBODBC_64_1696_20160511_0002_0.xml" konnte nicht gefunden werden." Bei Zeile:34 Zeichen:15 + $xmldata2.Load <<<< ("$file") + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException
Wie schon erwähnt liegen alle Dateien auf D: und nicht auf X: und die Variable $path ist auch korrekt angegeben.
Ich denke dass beide Fehlermeldungen irgendwie zusammenhängen.
-
> Lese Datei QDBODBC_64_1.xml> Ausnahme beim Aufrufen von "Load" mit 1 Argument(en): "Die Datei "X:\QDBODBC_64_1696_20160511_0002_0.xml" konnte nicht gefunden werden."Wir gehen mal davon aus, daß dieser Code hier die Fehlermeldung produziert:Write-Host "Lese Datei $file"$xmldata2.Load("$file")Hm - warum steht beim Write-Host etwas anderes in $file als dasXML-Objekt dann meldet? Weil Get-ChildItem - anders als Get-Item - alsStandardproperty zwar auch den Namen hat, aber bei Get-ChildItem ist daswirklich nur der Name. Du solltest .FullName verwenden :-)Write-Host "Lese Datei $($file.FullName)"$xmldata2.Load("$($file.FullName)")Zur Verdeutlichung, was ich meine:PS C:\users\public> Write-Host ( Get-ChildItem -Filter "*.txt" )ReadMe.txtPS C:\users\public> Write-Host ( Get-Item "*.txt" )C:\users\public\ReadMe.txtBeides die gleiche Datei, einmal mit LW/Pfad, einmal ohne...Tipp: Bei Get-ChildItem wäre -filter besser als |? - filtern immer links :-)
- Als Antwort markiert Tschenn1 Freitag, 3. Juni 2016 13:21