Aus XML-Dateien mehrere Daten auslesen und in einer Excel-Tabelle speichern
Guten Tag,
ich möchte aus mehreren Hundert XML-Dateien bestimmte Daten auslesen und in einer Excel-Tabelle zusammenführen. Die XML-Dateien liegen alle in einem Ordner. In dem Ordner sind allerdings nur bestimmte XML-Dateien relevant. Die relevanten XML-Dateien enthalten alle Beispielin ihrem Namen.
Die XML-Dateien sind prinzipiell alle gleich aufgebaut, sind aber nicht exakt gleich. Die Reihenfolge der Elemente ist mitunter eine andere. Die Namen der Elemente sind jedoch immer gleich.
Ich müsste bestimmte Elemente auslesen, wie z.B. Datum, Sprache, Vorname, Nachname und Email. Diese Elemente müssten aus allen hundert XML-Dateien der korrekten Spalte zugeordnet werden.
Für jede Hilfe wäre ich sehr dankbar!
Mit freundlichen Grüßen
Petrus
Folgend noch ein Beispiel einer XML-Datei:
ich möchte aus mehreren Hundert XML-Dateien bestimmte Daten auslesen und in einer Excel-Tabelle zusammenführen. Die XML-Dateien liegen alle in einem Ordner. In dem Ordner sind allerdings nur bestimmte XML-Dateien relevant. Die relevanten XML-Dateien enthalten alle Beispielin ihrem Namen.
Die XML-Dateien sind prinzipiell alle gleich aufgebaut, sind aber nicht exakt gleich. Die Reihenfolge der Elemente ist mitunter eine andere. Die Namen der Elemente sind jedoch immer gleich.
Ich müsste bestimmte Elemente auslesen, wie z.B. Datum, Sprache, Vorname, Nachname und Email. Diese Elemente müssten aus allen hundert XML-Dateien der korrekten Spalte zugeordnet werden.
Für jede Hilfe wäre ich sehr dankbar!
Mit freundlichen Grüßen
Petrus
Folgend noch ein Beispiel einer XML-Datei:
<?xml version="1.0" encoding="UTF-8"?>
<Beispielbericht>
<Einleitung>
<Informationen>
<Datum>2022-07-07</Datum>
<Sprache>deutsch</Sprache>
</Informationen>
<Software>
<Hersteller>Microsoft</Hersteller>
<Produktname>Office 365</Produktname>
<Version>1</Version>
</Software>
<Kontakt>
<Kontakt_Person1>
<Person>
<Vorname>Max</Vorname>
<Nachname>Musterfrau</Nachname>
<Beruf>Maler</Beruf>
</Person>
<Telefon>
<Vorwahl>000</Vorwahl>
<Rufnummer>0000</Rufnummer>
<Durchwahl>00000</Durchwahl>
</Telefon>
<Email>max@bsp.de</Email>
</Kontakt_Person1>
</Kontakt>
</Einleitung>
<Zusammenfassung>
<Allgemein>
<Keyfacts>1</Keyfacts>
<Ende>2</Ende>
</Allgemein>
</Zusammenfassung>
</Beispielbericht>
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 3379927774
Url: https://administrator.de/contentid/3379927774
Ausgedruckt am: 24.11.2024 um 03:11 Uhr
23 Kommentare
Neuester Kommentar
Moin,
Die Reihenfolge ist egal. Hauptsache die Elemente heißen immer gleich.
Ein wenig Powershell:
Die erste Zeile habe ich nicht getestet. Keine Lust mehrere Dateien zu erzeugen. Sollte aber gehen.
hth
Erik
Zitat von @Vollbio-Petrus:
Die XML-Dateien sind prinzipiell alle gleich aufgebaut, sind aber nicht exakt gleich. Die Reihenfolge der Elemente ist mitunter eine andere. Die Namen der Elemente sind jedoch immer gleich.
Die Reihenfolge ist egal. Hauptsache die Elemente heißen immer gleich.
Ich müsste bestimmte Elemente auslesen, wie z.B. Datum, Sprache, Vorname, Nachname und Email. Diese Elemente müssten aus allen hundert XML-Dateien der korrekten Spalte zugeordnet werden.
Ein wenig Powershell:
$files = get-childitem -File | Where-Object {$_.BaseName -match ".*beispiel.*"}
foreach ($file in $files) {
[xml]$xml=get-content $file
$result = New-Object psobject
$result|add-member NoteProperty "Datum" $xml.beispielbericht.einleitung.informationen.datum
$result|add-member NoteProperty "Sprache" $xml.beispielbericht.einleitung.informationen.sprache
$result|add-member NoteProperty "Name" $xml.beispielbericht.einleitung.kontakt.kontakt_person1.person.nachname
$result|add-member NoteProperty "Vorname" $xml.beispielbericht.einleitung.kontakt.kontakt_person1.person.vorname
$result|add-member NoteProperty "Email" $xml.beispielbericht.einleitung.kontakt.kontakt_person1.email
$result | export-csv X:\test\test.csv -NoTypeInformation -Delimiter ";" -append -Encoding utf8
remove-variable xml
remove-variable result
}
Die erste Zeile habe ich nicht getestet. Keine Lust mehrere Dateien zu erzeugen. Sollte aber gehen.
hth
Erik
Zitat von @Vollbio-Petrus:
Ich bin neu bei Powershell, vielleicht liegt es daran, dass ich es nicht zum laufen bekomme. Ich habe das Script als .ps1 abgespeichert in dem Ordner, wo sich alle XML Dateien befinden und ausgeführt mit PowerShell ISE. Jedoch tut sich dann nichts.
Ich bin neu bei Powershell, vielleicht liegt es daran, dass ich es nicht zum laufen bekomme. Ich habe das Script als .ps1 abgespeichert in dem Ordner, wo sich alle XML Dateien befinden und ausgeführt mit PowerShell ISE. Jedoch tut sich dann nichts.
Was heißt, es tut sich nichts? Angepasst auf Deine Verhältnisse? Und führe es mal mit der normalen Shell aus und nicht mit der ISE.
Zitat von @Vollbio-Petrus:
Es kommt direkt wieder die Eingabeaufforderung zurück. Also das PS U:\>. Das Script gibt mir keinen Output. Könnte es an der Execution Policy liegen?
VG
Was heißt, es tut sich nichts? Angepasst auf Deine Verhältnisse? Und führe es mal mit der normalen Shell aus und nicht mit der ISE.
Es kommt direkt wieder die Eingabeaufforderung zurück. Also das PS U:\>. Das Script gibt mir keinen Output. Könnte es an der Execution Policy liegen?
VG
Nö, liegt eher daran, dass er keine Dateien findet. Wenn die Execution Policy nicht stimmt, gibt es eine rote Fehlermeldung, dass Du das nicht darfst. Gib mal nur
get-childitem -File | Where-Object {$_.BaseName -match ".*beispiel.*"}
auf der Shell im gewünschten Ordner ein. Den Filter natürlich auf Deine Dateinamen anpassen.
Achja, das Skript gibt keine Meldung auf der Shell aus. Guck mal, ob ein CSV erzeugt wurde. Den Pfad in der Zeile 13 musst Du natürlich auch anpassen.
lg
Zitat von @Vollbio-Petrus:
Wenn ich die 1. Zeile des Scriptes eingebe, passiert nichts. Erst wenn ich den Filter weglasse, bekomme ich Output in PowerShell (Mode, LastWriteTime, Length, Name).
Dachte ich mir schon fast, dass es am Filter liegt. Der filtert offenbar dann alles weg und es gibt keine Ausgabe. Wie sieht denn der Name konkret aus und was ist immer gleich? Zwei, drei Beispiele wären nett.
<edit>Jetzt habe ich nochmal schnell getestet. Bei mir geht's.</edit>
Zitat von @McLion:
Vielleicht
durch
ersetzen (Punkt hinter dem Wort "beispiel" entfernen)? Eventuell "Beispiel" schreiben, oder *eispiel*?
Vielleicht
{$_.BaseName -match ".*beispiel.*"}
{$_.BaseName -match ".*beispiel*"}
Nein. Das ist eine Regex. Der Punkt ist die Wildcard für ein beliebiges Zeichen und der Stern ist der Quantifier für beliebig oft. Beide Zeichen müssen in der Reihenfolge vorhanden sein.
Zitat von @Vollbio-Petrus:
Wenn ich den Filter weglasse, funktioniert es bei mir teils. Ich bekomme dann eine csv Datei mit folgenden Output:
Wenn ich den Filter weglasse, funktioniert es bei mir teils. Ich bekomme dann eine csv Datei mit folgenden Output:
"Datum";"Sprache";"Name";"Vorname";"Email"
;;;;
OK, dann sind die angegebenen Elemente leer oder nicht vorhanden. Du musst das natürlich anpassen an die Struktur der konkreten XMLs.
Die Namen der Dateien, die relevant sind, bestehen aus einer Ziffernfolge und enden mit -xml. Alle anderen Dateien haben eine andere Endung.
Endung im Sinne der Name vor der Dateiendung endet so? Oder Endung im Sinne von Dateiendung? Ich vermute mal das erste. Dann sieht der Filter so aus:
Where-Object {$_.BaseName -match ".*xml$"}
Sollte es die Dateiendung sein, dann so
Where-Object {$_.extension -eq '.xml'}
Auch ist die Pfad-Reihenfolge der Elemente in den Dateien unterschiedlich. Z.B. Datum findet sich manchmal an einer späteren Stelle.
Was heißt das? Wichtig ist, dass die Pfade immer gleich ist. In welcher Reihenfolge die Elemente genannt werden, ist vollkommen egal. Also das hier geht:
<main>
<person>
<givenname>
Hans
</givenname>
<surname>
Meier
</surname>
</person>
</main>
identisch mit
<main>
<person>
<surname>
Meier
</surname>
<givenname>
Hans
</givenname>
</person>
</main>
Und das nicht:
<main>
<person>
<surname>
Meier
</surname>
<givenname>
Hans
</givenname>
</person>
</main>
nicht identisch mit
<main>
<surname>
Meier
</surname>
<givenname>
Hans
</givenname>
</main>
hth
Erik
Seltsam. Ich habe das oben geschriebene noch einmal getestet mit vier Dateien. Bei mir geht's. Mein CSV sieht hinterher so aus:
Gib mal bei get-childitem vorsichtshalber noch den Pfad mit an:
"Datum";"Sprache";"Name";"Vorname";"Email"
"2022-07-07";"deutsch";"Musterfrau";"Max";"max@bsp.de"
"2022-07-07";"deutsch";"Musterfrau";"Max";"max@bsp.de"
"2022-07-07";"deutsch";"Musterfrau";"Max";"max@bsp.de"
"2022-07-07";"deutsch";"Musterfrau";"Max";"max@bsp.de"
Gib mal bei get-childitem vorsichtshalber noch den Pfad mit an:
get-childitem -path x:\ordner\unterordner\ -file
Gerne Nicht vergessen, den Thread als gelöst zu markieren.
Kannst Du bitte das fertige Script hier posten? Vielen Dank!