vollbio-petrus
Goto Top

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:

<?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>

Content-ID: 3379927774

Url: https://administrator.de/contentid/3379927774

Ausgedruckt am: 24.11.2024 um 03:11 Uhr

McLion
McLion 19.07.2022 um 16:42:22 Uhr
Goto Top
Hi!
Hier muss Du wohl was programmieren. Fertige Tools dafür kenne ich nicht.
erikro
erikro 19.07.2022 aktualisiert um 16:49:29 Uhr
Goto Top
Moin,

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. face-wink Sollte aber gehen.

hth

Erik
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 09:37:42 Uhr
Goto Top
Hi @erikro,

erstmal vielen Dank.

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.

Über weitere Hilfe wäre ich sehr dankbar.

VG Petrus
erikro
erikro 20.07.2022 um 09:39:11 Uhr
Goto Top
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.

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.
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 09:49:04 Uhr
Goto Top
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
erikro
erikro 20.07.2022 um 10:08:10 Uhr
Goto Top
Zitat von @Vollbio-Petrus:

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
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 10:50:17 Uhr
Goto Top
auf der Shell im gewünschten Ordner ein.

Was genau meinst du damit? Ich habe PowerShell geöffnet und dort das Script ausgeführt. Pfad und Filter sind angepasst. Die csv wird nicht erzeugt bei mir.

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).

Vielen Dank & lg
erikro
erikro 20.07.2022 aktualisiert um 11:11:22 Uhr
Goto Top
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. face-wink 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>
McLion
McLion 20.07.2022 aktualisiert um 11:52:23 Uhr
Goto Top
Vielleicht
{$_.BaseName -match ".*beispiel.*"}  
durch
{$_.BaseName -match ".*beispiel*"}  
ersetzen (Punkt hinter dem Wort "beispiel" entfernen)? Eventuell "Beispiel" schreiben, oder *eispiel*?
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 12:01:46 Uhr
Goto Top
Wenn ich den Filter weglasse, funktioniert es bei mir teils. Ich bekomme dann eine csv Datei mit folgenden Output:

"Datum";"Sprache";"Name";"Vorname";"Email"  
;;;;

Die Namen der Dateien, die relevant sind, bestehen aus einer Ziffernfolge und enden mit -xml. Alle anderen Dateien haben eine andere Endung. Also der Ordner sieht so aus:

12345-2022-xml
12345-2022-test
12345-2022-xml
12345-2022-test
...

Auch ist die Pfad-Reihenfolge der Elemente in den Dateien unterschiedlich. Z.B. Datum findet sich manchmal an einer späteren Stelle.

Vielen Dank & lg
erikro
erikro 20.07.2022 um 12:10:18 Uhr
Goto Top
Zitat von @McLion:

Vielleicht
{$_.BaseName -match ".*beispiel.*"}  
durch
{$_.BaseName -match ".*beispiel*"}  
ersetzen (Punkt hinter dem Wort "beispiel" entfernen)? Eventuell "Beispiel" schreiben, oder *eispiel*?

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.
erikro
erikro 20.07.2022 um 12:24:44 Uhr
Goto Top
Zitat von @Vollbio-Petrus:

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
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 13:09:39 Uhr
Goto Top
Hi Erik,

erstmal vielen Dank für deine Hilfe.

Genau, Endung im Sinne der Name vor der Dateiendung endet so.

Ich habe gerade die Pfade überprüft, diese sollten immer gleich sein. Wenn ich den Filter mit drin habe, wird kein Dokument erstellt. Aber das sollte kein Problem sein, da die anderen nicht relevanten Dateien andere Pfade haben. So wie ich es verstanden habe, sollten diese dann sowieso nicht in der Tabelle auftauchen.

Das einzige was jetzt noch nicht funktioniert, ist die Befüllung der Tabelle. Die Überschriften stehen da, aber in den Zeilen darunter sind nicht die Daten aus den XML Dateien. Die Pfade habe ich mehrfach überprüft und sie müssten übereinstimmen. Woran kann das liegen?

lg
erikro
erikro 20.07.2022 um 13:43:03 Uhr
Goto Top
Stell mal Dein angepasstes Skript und eine Beispieldatei hier rein. Die Daten in der Datei kannst Du ja mit xxx ersetzen.
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 14:17:57 Uhr
Goto Top
Ich habe den Filter herausgenommen und nur 2 Variablen der Einfachheit erstmal drinnen gelassen.

Das XML Dokument (siehe ganz oben) habe ich exakt genau so 4 mal in einen Ordner abgelegt (2mal mit der Endung -xml und 2mal -test im Namen). Von dort versuche ich testweise die Daten herauszuziehen. Bisher werden mir nur die 2 Überschriften angezeigt (Datum und Sprache).

$files = get-childitem -File

 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 | export-csv C:\Users\test.csv -NoTypeInformation -Delimiter ";" -append -Encoding utf8  

     remove-variable xml
     remove-variable result

}

Vielen Dank & lg
erikro
erikro 20.07.2022 um 14:36:42 Uhr
Goto Top
Seltsam. Ich habe das oben geschriebene noch einmal getestet mit vier Dateien. Bei mir geht's. Mein CSV sieht hinterher so aus:

"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
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 15:01:49 Uhr
Goto Top
Wenn ich den Pfad angebe, dann wird nun in der Konsole Mode, LastWriteTime, Length und Name angezeigt von allen 4 Dateien. Die Datei wird erstellt, bleibt allerdings leer bis auf die Überschrift, so wie vorher.

Zudem kommt jetzt die gleiche (bis auf den Dateinamen) folgende Fehlermeldung 4mal hintereinander:

get-content : Der Pfad "U:\2131221-test.xml" kann nicht gefunden werden, da er nicht vorhanden ist.  
In Zeile:5 Zeichen:16
+      [xml]$xml=get-content $file
+                ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (U:\2131221-beispiel.xml:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Vielen Dank & lg
erikro
erikro 20.07.2022 um 15:34:22 Uhr
Goto Top
Dann ändere das auf

[xml]$xml=get-content $file.fullname
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 15:50:58 Uhr
Goto Top
Es funktioniert jetzt. Du bist mein Held face-smile Danke dir sehr!

LG Petrus
erikro
erikro 20.07.2022 um 16:00:12 Uhr
Goto Top
Zitat von @Vollbio-Petrus:

Es funktioniert jetzt. Du bist mein Held face-smile Danke dir sehr!

LG Petrus

Gerne face-smile Nicht vergessen, den Thread als gelöst zu markieren.
McLion
McLion 20.07.2022 um 16:08:29 Uhr
Goto Top
Zitat von @Vollbio-Petrus:

Es funktioniert jetzt. Du bist mein Held face-smile Danke dir sehr!

LG Petrus

Kannst Du bitte das fertige Script hier posten? Vielen Dank!
Vollbio-Petrus
Vollbio-Petrus 20.07.2022 um 16:16:56 Uhr
Goto Top
Hier das finale Script:

$files = get-childitem -path X:\Test_Ordner\ -file | Where-Object {$_.BaseName -match ".*beispiel$"}  

 foreach ($file in $files) {

     [xml]$xml=get-content $file.fullname
     $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 | export-csv X:\Results\test.csv -NoTypeInformation -Delimiter ";" -append -Encoding utf8  

     remove-variable xml
     remove-variable result

}
McLion
McLion 20.07.2022 um 16:45:12 Uhr
Goto Top
Vielen Dank!