Top-Themen

Aktuelle Themen (A bis Z)

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Mittels Batch mehrere Einträge aus mehreren XML-Dateien in eine Textdatei schreiben

Frage Entwicklung Batch & Shell

Mitglied: tardezyx

tardezyx (Level 1) - Jetzt verbinden

29.04.2010, aktualisiert 22:38 Uhr, 7470 Aufrufe, 15 Kommentare

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

01.
dir /B /s *.nfo > nfo-list.txt
Die XML-Dateien seien wiederum wie folgt aufgebaut ("..." ist unwichtiges Zeugs):

01.
<?xml version="1.0" encoding="utf-8"?> 
02.
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
03.
  <title>Dies ist ein Titel</title> 
04.
  <year>2006</year> 
05.
  <durance>5.3</durance> 
06.
  <members>1,217</members> 
07.
  <lead>Alfred / Josef / Mike</lead> 
08.
  ... 
09.
  <extract> 
10.
    <details> 
11.
      <astate> 
12.
        <hidden>stealth</hidden> 
13.
        ... 
14.
      </astate> 
15.
      <vstate> 
16.
        <hidden>block</hidden> 
17.
        ... 
18.
      </vstate> 
19.
    </details> 
20.
  </extract> 
21.
</data>
Herauskommen soll hierbei die folgende Zeile (Tabulatorenabstand):

01.
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ß!
Mitglied: bastla
30.04.2010 um 00:15 Uhr
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:
01.
@echo off & setlocal enabledelayedexpansion 
02.
set "Basis=D:\Startordner" 
03.
set "CSV=Gesamt.csv" 
04.
set "Delim=;" 
05.
 
06.
pushd "%Basis%" 
07.
del "%CSV%" 2>nul 
08.
for /f "delims=" %%i in ('dir /s /b *.nfo') do ( 
09.
    set "Record=" 
10.
    for %%f in ("<title>" "<year>" "<durance>" "<lead>" "<hidden>") do ( 
11.
        for /f "tokens=3 delims=<>" %%v in ('findstr %%f %%i') do set "Record=!Record!%Delim%%%v" 
12.
13.
    >>"%CSV%" echo !Record:~1! 
14.
15.
popd
Allerdings solltest Du keine Geschwindigkeitsrekorde erwarten ...

Grüße
bastla
Bitte warten ..
Mitglied: tardezyx
30.04.2010 um 00:48 Uhr
Hallo bastla,

danke! Das sieht schon sehr gut aus - doch haut noch nicht ganz hin, weil ich dir die Ordnerstruktur vorenthalten habe, wie ich grad merke ;)

Die Verzeichnisse und Dateinamen enthalten Leerzeichen, so dass er sie bei dem jetzigen Code nicht findet. Er sucht statt nach Datei "abcd xy (2003).nfo" jetzt nach den Dateien "abcd", "xy" und "(2003).nfo". Wahrscheinlich sucht er auch in den falschen Verzeichnissen, da diese ähnlich benannt sind. Dann würde es wunderbar hinhauen.

Dann würde mich noch interessieren, ob es möglich ist, nach dem Eintrag in den <hidden> - Tags einen weiteren folgen zu lassen, allerdings mit einem anderen Trennzeichen (Doppelpunkt und Leerzeichen?), so dass beide Einträge später dann in Excel in derselben Spalte übernommen werden. Diese Einträge befinden sich nach den <hidden> - Tags zwischen den <movement> - Tags bzw. den <size> - Tags (also Reihenfolge stimmt hier auch - kann man die an diesem auch Punkt umkehren? - das wäre wesentlich besser).

Also XML derart:

01.
(...alles wie oben...) 
02.
  <extract> 
03.
    <details> 
04.
      <astate> 
05.
        <hidden>stealth</hidden> 
06.
        <movement>move</movement> 
07.
        ... 
08.
      </astate> 
09.
      <astate> 
10.
        <hidden>stealth2</hidden> 
11.
        <movement>move2</movement> 
12.
        ... 
13.
      </astate> 
14.
      <vstate> 
15.
        <hidden>block</hidden> 
16.
        ... 
17.
        <size>large</size> 
18.
      </vstate> 
19.
    </details> 
20.
  </extract> 
21.
</data>
So dass es dann in der CSV so aussieht:

01.
Dies ist ein Titel;2006;5.3;Alfred / Josef / Mike;stealth: move;stealth2: move2;block: large
Danke nochmal und Gruß!

EDIT: Was ist, wenn Ausrufezeichen in den Daten auftauchen? Das ist in der Mehrzahl der Dateien der Fall.

EDIT 2: Leerzeichenproblem erledigt: habe einfach zwei " in diese Zeilen eingefügt:

for /f "tokens=3 delims=<>" %%v in ('findstr %%f "%%i"') do set "Record=!Record!%Delim%%%v"
Bitte warten ..
Mitglied: bastla
30.04.2010 um 01:30 Uhr
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:
01.
@echo off & setlocal 
02.
set "Basis=D:\Startordner" 
03.
set "CSV=Gesamt.csv" 
04.
set "Delim=;" 
05.
 
06.
pushd "%Basis%" 
07.
del "%CSV%" 2>nul 
08.
for /f "delims=" %%i in ('dir /s /b *.nfo') do call :ProcessFile "%%i" 
09.
popd 
10.
goto :eof 
11.
 
12.
:ProcessFile 
13.
set "Record=" 
14.
for %%f in ("<title>" "<year>" "<durance>" "<lead>" "<hidden>") do for /f "tokens=3 delims=<>" %%v in ('findstr %%f %1') do call :ProcessField "%%v" 
15.
>>"%CSV%" echo %Record:~1% 
16.
goto :eof 
17.
 
18.
:ProcessField 
19.
set "Record=%Record%%Delim%%~1" 
20.
goto :eof
Bis hierher war es einfach möglich, die einzelnen Tags in der gewünschten Reihenfolge mit "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
Bitte warten ..
Mitglied: tardezyx
30.04.2010 um 02:03 Uhr
Hey, spitze - genau so! Danke dir wie Sau! ;)

Gut, dass du dich noch nicht weiter rangesetzt hast.

Jetzt, wo ich das so sehe, wäre es vorteilhafter, dass er das <hidden> nur aus dem <vstate> holt und danach, was in der <size> steht. Es steht aber in den XML fast immer noch was zwischen <vstate> und <hidden>.

Das sieht in der XML so aus:

01.
  ... 
02.
  <extract> 
03.
    <details> 
04.
      <astate> 
05.
        ... 
06.
      </astate> 
07.
      <astate> 
08.
        ... 
09.
      </astate> 
10.
      <vstate> 
11.
        ... 
12.
        <hidden>block</hidden> 
13.
        ... 
14.
        <size>large</size> 
15.
      </vstate> 
16.
    </details> 
17.
  </extract> 
18.
</data>
Ansonsten alles wie gehabt. Bestimmt knifflig.

Das mit den Doppelpunkten wäre erstmal egal. Falls es einfach gänge, kannst du es mir ja trotzdem noch zeigen. Vielleicht brauch ich's mal.

Guts Nächtle ;)

EDIT: Oje, jetzt hat er Probleme mit "&" im Dateiname und sagt: "Der Befehl "amp" ist entweder falsch geschrieben oder konnte nicht gefunden werden."
Bitte warten ..
Mitglied: bastla
30.04.2010 um 02:18 Uhr
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:
01.
:ProcessFile 
02.
set "Record=" 
03.
for %%f in ("<title>" "<year>" "<durance>" "<lead>") do for /f "tokens=3 delims=<>" %%v in ('findstr %%f %1') do call :ProcessField "%%v" 
04.
set "Hidden=" 
05.
for /f "tokens=3 delims=<>" %%v in ('findstr "<hidden>" %1') do set "Hidden=%%v" 
06.
for /f "tokens=3 delims=<>" %%v in ('findstr "<size>" %1') do set "Hidden=%Hidden%: %%v" 
07.
>>"%CSV%" echo %Record%%Hidden% 
08.
goto :eof 
09.
 
10.
:ProcessField 
11.
set "Record=%Record%%~1%Delim%" 
12.
goto :eof
Grüße
bastla
Bitte warten ..
Mitglied: tardezyx
30.04.2010 um 10:23 Uhr
Hallo bastla,

super!

Jetzt ist nur noch das Amp-Problem vorhanden, also das "&" im <title>. Falls es im Verzeichnis- und Dateinamen auftaucht, macht es keine Probleme, aber er hört sofort im <title> (dieser entspricht meist dem Dateinamen) beim "&" auf und geht zur nächsten .nfo-Datei.

Das Ergebnis sieht dann so aus:

01.
Dies ist ein Titel;2006;5.3;Alfred / Josef / Mike;block: large 
02.
Bonnie 
03.
Das ist auch ein Titel;2003;6.9;Fred / Harald;block: small
Bonnie wäre eigentlich bspw. Bonnie & Clyde.

Gruß!
Bitte warten ..
Mitglied: bastla
30.04.2010 um 10:52 Uhr
Hallo tardezyx!

Dann spendieren wir dem Batch eben noch eine Zeile 11a:
set "Record=%Record:&=^&%"
Grüße
bastla
Bitte warten ..
Mitglied: tardezyx
30.04.2010 um 11:22 Uhr
Hallo,

da kommt derselbe Fehler und er macht jetzt aus Bonnie & Clyde:

01.
Bonnie ^^
Und geht wieder auf die nächste Zeile.

Gruß!
Bitte warten ..
Mitglied: bastla
30.04.2010 um 11:32 Uhr
Hallo tardezyx!

Nur zur Sicherheit: Das gesamte Unterprogramm sieht jetzt so aus?
01.
:ProcessField 
02.
set "Record=%Record%%~1%Delim%" 
03.
set "Record=%Record:&=^&%" 
04.
goto :eof
Grüße
bastla
Bitte warten ..
Mitglied: tardezyx
30.04.2010 um 11:41 Uhr
Jap. Ich nutze Windows 7 x64 Pro.

Er sagt immer noch: "Der Befehl "amp" ist entweder falsch geschrieben oder konnte nicht gefunden werden."

Gruß!
Bitte warten ..
Mitglied: bastla
30.04.2010 um 12:43 Uhr
Hallo tardezyx!

Wenn ja ohnehin ein Import der Daten in Excel geplant ist, sollte es ja kein Problem sein, wenn die Felder unter Anführungszeichen stehen - versuch es daher mal mit dieser Variante:
01.
:ProcessField 
02.
set Record=%Record%%1%Delim% 
03.
goto :eof
Grüße
bastla
Bitte warten ..
Mitglied: tardezyx
30.04.2010 um 13:29 Uhr
Alles klar - danke dir nochmal!

Gruß!
Bitte warten ..
Mitglied: tardezyx
30.04.2010 um 17:14 Uhr
Hallo nochmal,

ich probiere gerade herum, so dass er mir während dieses Prozesses den gerade ablaufenden Titel anzeigt, den er in der Datei findet. Ich habe es hinbekommen, dass er mir die Datei anzeigt, der Titel wäre noch besser.

Ich habe da nur die 3. Zeile eingefügt:

01.
:ProcessFile 
02.
set "Record=" 
03.
for %%f in ("<title>") do echo %%i
%%i ist ja offensichtlich der Dateiname? Welche Variable ist aber der Inhalt von <title>?

Danke und Gruß!
Bitte warten ..
Mitglied: bastla
30.04.2010 um 17:23 Uhr
Hallo tardezyx!
%%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
Grüße
bastla
Bitte warten ..
Mitglied: tardezyx
30.04.2010 um 17:39 Uhr
Danke, klappt!

Jetzt noch 'ne schöne GUI rundrum und wir sind fertig - Spässle ;)

Gruß!
Bitte warten ..
Ähnliche Inhalte
Batch & Shell
Mittels Batch bestimmte Information aus unbekannter Textdatei auslesen und in XML-Datei schreiben
gelöst Frage von tardezyxBatch & Shell3 Kommentare

Hallo, es sind innerhalb eines Verzeichnisses sehr viele Unterordner vorhanden, in denen sich jeweils eine Textdatei befindet, deren Strukturen ...

Batch & Shell
Mehrere Dateien in einer Textdatei per batch oder script zusammenführen
gelöst Frage von HausbootBatch & Shell24 Kommentare

Guten Tag in die Runde der Fachleute. Ich habe folgendes Problem: In einem Unterordner liegen Dateien mit verschiedenen Dateinamen ...

PHP
Mehrere XML Dateien mit PHP auslesen
gelöst Frage von Jens1985PHP4 Kommentare

Hi ich würde gerne mit PHP mehrere xml Dateien auslesen. Mit nur einer xml datei klappt es wunderbar. Momentan ...

Batch & Shell
Textdatei aus mehreren .sfx Dateien löschen
gelöst Frage von BustedDiceBatch & Shell3 Kommentare

Hallo zusammen brauch mal wieder Hilfe bei einem Batch.Ich möchte eine .txt mit dem Name hilfe.txt aus ca. 200 ...

Neue Wissensbeiträge
Internet

USA: Die FCC schaff die Netzneutralität ab

Information von Frank vor 3 StundenInternet2 Kommentare

Jetzt beschädigt US-Präsident Donald Trump auch noch das Internet. Der neu eingesetzte FCC-Chef Ajit Pai ist bekannter Gegner einer ...

DSL, VDSL

ALL-BM200VDSL2V - Neues VDSL-Modem mit Vectoring von Allnet

Information von Lochkartenstanzer vor 6 StundenDSL, VDSL1 Kommentar

Moin, Falls jemand eine Alternative zu dem draytek sucht: Gruß lks

Windows 10

Microsoft bestätigt DMA-Policy-Problem in Win10 v1709

Information von DerWoWusste vor 6 StundenWindows 10

Wer sein Gerät mit der DMA-Policy absichert, bekommt evtl. Hardwareprobleme in v1709 von Win10. Warum? Weil v1709 endlich "richtig" ...

Verschlüsselung & Zertifikate

Die Hölle friert ein weiteres Stück zu: Microsoft integriert OpenSSH in Windows

Information von ticuta1 vor 10 StundenVerschlüsselung & Zertifikate

Interessant Die Hölle friert ein weiteres Stück zu: Microsoft integriert OpenSSH in Windows SSH-Kommando in CMD.exe und PowerShell

Heiß diskutierte Inhalte
Netzwerkmanagement
Mehrere Netzwerkadapter in einem PC zu einem Switch zusammenfügen
Frage von prodriveNetzwerkmanagement21 Kommentare

Hallo zusammen Vorweg, ich konnte schon einige IT-Probleme mit Hilfe dieses Forums lösen. Wirklich klasse hier! Doch für das ...

Windows Server
RODC kann nicht aus Domäne entfernt werden
Frage von NilsvLehnWindows Server19 Kommentare

HAllo, ich arbeite in einem Universitätsnetzwerk mit 3 Standorten. Die Standorte haben alle ein ESXi Cluster und auf diesen ...

Hardware
Kein Bild mit nur einer bestimmten Grafikkarten - Mainboard Konfiguration
gelöst Frage von bestelittHardware18 Kommentare

Hallo zusammen, ich hatte schon einmal eine ähnliche Frage gestellt. Damals hatte ich genau das gleiche Problem. Allerdings lies ...

Hardware
Links klick bei Maus funktioniert nicht
gelöst Frage von Pablu23Hardware16 Kommentare

Hallo erstmal. Ich habe ein Problem mit meiner relativ alten maus jedoch denke ich nicht das es an der ...