Mittels Batch mehrere Einträge aus mehreren XML-Dateien in eine Textdatei schreiben
aus mehreren Dateien (identische Grammatik) mit unterschiedlichen Inhalten sollen mehrere Einträge an unterschiedlichen Positionen (aber innerhalb identischer Tags) in einer separaten neuen Datei übersichtlich gespeichert werden
Hallo,
eigentlich steht das Problem schon im Titel ;)
Ich habe mehrere tausend XML-Dateien, die der gleichen Grammatik folgen und würde gerne bestimmte Informationen daraus in eine einzige Textdatei schreiben, wobei die einzelnen Einträge mittels selbst definiertem Trennzeichen (Tabulator oder Semikolon ist erstmal egal - dient zum späteren Datenimport in Excel) in eine Zeile geschrieben werden sollen und für jede XML-Datei genau 1 Zeile belegt werden soll.
Die XML-Dateien befinden sich darüber hinaus in Unterordnern, so dass man die unterschiedlichen Pfade in den Batch-Aufruf integrieren müsste. Es ist mir aber bereits gelungen, sämtliche Pfade zu den .nfo-Dateien vorab in einer Datei mittels diesem Code abzulegen, der wiederum mittels der Datei list_all_nfos.bat gestartet wird (diese könnte man also in die Batch-Prozedur integrieren):
Die XML-Dateien seien wiederum wie folgt aufgebaut ("..." ist unwichtiges Zeugs):
Herauskommen soll hierbei die folgende Zeile (Tabulatorenabstand):
Danach soll automatisch ein Zeilenumbruch eingefügt und die nächste .nfo-Datei geparst werden, bis das Programm keine weiteren findet (also die nfo-list.txt am Ende angekommen ist).
Wichtig hierbei ist, dass die herauszuziehenden Informationen bei allen Dateien immer zwischen denselben Tags liegen (alle XML-Dateien unterliegen derselben Grammatik), d.h. der Titel liegt immer zwischen <title> und </title>, das Jahr immer zwischen <year> und </year> usw., aber wo sich diese Tags konkret befinden, ist von Datei zu Datei unterschiedlich, da sich jeweils eine weitere Menge an unterschiedlichen Informationen darin befinden. Außerdem kommen die meisten gesuchten Tags nur 1x pro Datei vor, d.h. es gibt nur einen Titel und nur ein Jahr usw., aber es gibt 2x den <hidden> & </hidden> Tag, so dass man dort den vorangehenden Tag mit einbeziehen müsste - also <astate> & <vstate>.
Wäre das überhaupt mittels Batch-Programmierung umzusetzen?
Danke und Gruß!
Hallo,
eigentlich steht das Problem schon im Titel ;)
Ich habe mehrere tausend XML-Dateien, die der gleichen Grammatik folgen und würde gerne bestimmte Informationen daraus in eine einzige Textdatei schreiben, wobei die einzelnen Einträge mittels selbst definiertem Trennzeichen (Tabulator oder Semikolon ist erstmal egal - dient zum späteren Datenimport in Excel) in eine Zeile geschrieben werden sollen und für jede XML-Datei genau 1 Zeile belegt werden soll.
Die XML-Dateien befinden sich darüber hinaus in Unterordnern, so dass man die unterschiedlichen Pfade in den Batch-Aufruf integrieren müsste. Es ist mir aber bereits gelungen, sämtliche Pfade zu den .nfo-Dateien vorab in einer Datei mittels diesem Code abzulegen, der wiederum mittels der Datei list_all_nfos.bat gestartet wird (diese könnte man also in die Batch-Prozedur integrieren):
dir /B /s *.nfo > nfo-list.txt
Die XML-Dateien seien wiederum wie folgt aufgebaut ("..." ist unwichtiges Zeugs):
<?xml version="1.0" encoding="utf-8"?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<title>Dies ist ein Titel</title>
<year>2006</year>
<durance>5.3</durance>
<members>1,217</members>
<lead>Alfred / Josef / Mike</lead>
...
<extract>
<details>
<astate>
<hidden>stealth</hidden>
...
</astate>
<vstate>
<hidden>block</hidden>
...
</vstate>
</details>
</extract>
</data>
Herauskommen soll hierbei die folgende Zeile (Tabulatorenabstand):
Dies ist ein Titel 2006 5.3 Alfred / Josef / Mike stealth block
Danach soll automatisch ein Zeilenumbruch eingefügt und die nächste .nfo-Datei geparst werden, bis das Programm keine weiteren findet (also die nfo-list.txt am Ende angekommen ist).
Wichtig hierbei ist, dass die herauszuziehenden Informationen bei allen Dateien immer zwischen denselben Tags liegen (alle XML-Dateien unterliegen derselben Grammatik), d.h. der Titel liegt immer zwischen <title> und </title>, das Jahr immer zwischen <year> und </year> usw., aber wo sich diese Tags konkret befinden, ist von Datei zu Datei unterschiedlich, da sich jeweils eine weitere Menge an unterschiedlichen Informationen darin befinden. Außerdem kommen die meisten gesuchten Tags nur 1x pro Datei vor, d.h. es gibt nur einen Titel und nur ein Jahr usw., aber es gibt 2x den <hidden> & </hidden> Tag, so dass man dort den vorangehenden Tag mit einbeziehen müsste - also <astate> & <vstate>.
Wäre das überhaupt mittels Batch-Programmierung umzusetzen?
Danke und Gruß!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 141792
Url: https://administrator.de/contentid/141792
Ausgedruckt am: 26.11.2024 um 14:11 Uhr
15 Kommentare
Neuester Kommentar
Hallo tardezyx und willkommen im Forum!
Soferne es in den Daten kein "!" gibt und die Reihenfolge von "<astate>" und "<vstate>" immer gleich ist, könnte das so gehen:
Allerdings solltest Du keine Geschwindigkeitsrekorde erwarten ...
Grüße
bastla
Soferne es in den Daten kein "!" gibt und die Reihenfolge von "<astate>" und "<vstate>" immer gleich ist, könnte das so gehen:
@echo off & setlocal enabledelayedexpansion
set "Basis=D:\Startordner"
set "CSV=Gesamt.csv"
set "Delim=;"
pushd "%Basis%"
del "%CSV%" 2>nul
for /f "delims=" %%i in ('dir /s /b *.nfo') do (
set "Record="
for %%f in ("<title>" "<year>" "<durance>" "<lead>" "<hidden>") do (
for /f "tokens=3 delims=<>" %%v in ('findstr %%f %%i') do set "Record=!Record!%Delim%%%v"
)
>>"%CSV%" echo !Record:~1!
)
popd
Grüße
bastla
Hallo tardezyx!
Hinsichtlich der Leerzeichen in den Verzeichnis-/Dateinamen trifft mich eine Mitschuld - üblicher Weise berücksichtige ich das bereits vorsorglich (indem in Zeile 11 "%%i" unter Anführungszeichen gesetzt wird [Edit] hatte Dein EDIT 2 noch nicht gesehen [/Edit]); das hatte ich zwar in meiner ersten Version (welche mit Unterprogrammen arbeitete) auch getan - beim Versuch, die Performance zu verbessern, indem ich auf die Variante mit geschachtelten Schleifen umstellte, sind die Anführungszeichen dann leider auf der Strecke geblieben ...
... umso ärgerlicher, da ich nun (wegen der Ausrufezeichen) ohnehin wieder Unterprogramme verwenden muss.
Ohne Berücksichtigung der Zusatzanforderung hinsichtlich der "<movement>"- und "<size>"-Tags sähe das dann zunächst so aus:
Bis hierher war es einfach möglich, die einzelnen Tags in der gewünschten Reihenfolge mit "
Da es inzwischen schon etwas spät (bzw früh ) ist, muss ich Dich in dieser Hinsicht leider auf später am Tag vertrösten ...
Grüße
bastla
Hinsichtlich der Leerzeichen in den Verzeichnis-/Dateinamen trifft mich eine Mitschuld - üblicher Weise berücksichtige ich das bereits vorsorglich (indem in Zeile 11 "%%i" unter Anführungszeichen gesetzt wird [Edit] hatte Dein EDIT 2 noch nicht gesehen [/Edit]); das hatte ich zwar in meiner ersten Version (welche mit Unterprogrammen arbeitete) auch getan - beim Versuch, die Performance zu verbessern, indem ich auf die Variante mit geschachtelten Schleifen umstellte, sind die Anführungszeichen dann leider auf der Strecke geblieben ...
... umso ärgerlicher, da ich nun (wegen der Ausrufezeichen) ohnehin wieder Unterprogramme verwenden muss.
Ohne Berücksichtigung der Zusatzanforderung hinsichtlich der "<movement>"- und "<size>"-Tags sähe das dann zunächst so aus:
@echo off & setlocal
set "Basis=D:\Startordner"
set "CSV=Gesamt.csv"
set "Delim=;"
pushd "%Basis%"
del "%CSV%" 2>nul
for /f "delims=" %%i in ('dir /s /b *.nfo') do call :ProcessFile "%%i"
popd
goto :eof
:ProcessFile
set "Record="
for %%f in ("<title>" "<year>" "<durance>" "<lead>" "<hidden>") do for /f "tokens=3 delims=<>" %%v in ('findstr %%f %1') do call :ProcessField "%%v"
>>"%CSV%" echo %Record:~1%
goto :eof
:ProcessField
set "Record=%Record%%Delim%%~1"
goto :eof
findstr
" jeweils aus der übergebenen Datei heraussuchen zu lassen (und zu einer Zeile zusammenzufügen) - um die zwischen den "<hidden>"-Werten liegenden Tags zu berücksichtigen, wird es allerdings erforderlich sein, die gesamte Datei zeilenweise durchzugehen.Da es inzwischen schon etwas spät (bzw früh ) ist, muss ich Dich in dieser Hinsicht leider auf später am Tag vertrösten ...
Grüße
bastla
Hallo tardezyx!
Wenn nur das letzte "<hidden>" benötigt wird und es "<size>" nur einmal geben sollte, könnte sich das doch jetzt noch ausgehen - versuch es mit folgendem (ungetesten) Ersatz des Teiles ab Zeile 12:
Grüße
bastla
Wenn nur das letzte "<hidden>" benötigt wird und es "<size>" nur einmal geben sollte, könnte sich das doch jetzt noch ausgehen - versuch es mit folgendem (ungetesten) Ersatz des Teiles ab Zeile 12:
:ProcessFile
set "Record="
for %%f in ("<title>" "<year>" "<durance>" "<lead>") do for /f "tokens=3 delims=<>" %%v in ('findstr %%f %1') do call :ProcessField "%%v"
set "Hidden="
for /f "tokens=3 delims=<>" %%v in ('findstr "<hidden>" %1') do set "Hidden=%%v"
for /f "tokens=3 delims=<>" %%v in ('findstr "<size>" %1') do set "Hidden=%Hidden%: %%v"
>>"%CSV%" echo %Record%%Hidden%
goto :eof
:ProcessField
set "Record=%Record%%~1%Delim%"
goto :eof
bastla
Hallo tardezyx!
Grüße
bastla
%%i ist ja offensichtlich der Dateiname? Welche Variable ist aber der Inhalt von <title>?
Der "title", aber auch alle anderen in der Schleife ausgelesenen Felder, wird als "%%v" an das Unterprogramm ":ProcessField
" übergeben und kommt dort als %1 (unter Anführungszeichen stehend) an - da der Titel das erste Feld des Datensatzes darstellt (vorher ist die entsprechende Variable "leer" bzw genauer: "not defined"), könntest Du unmittelbar nach ":ProcessField
" die folgende Zeile einfügen:if not defined Record echo %1
bastla