mispel
Goto Top

Frage zum Verteilen von xml-Dateien nach ihren Inhalten auf der Grundlage von Daten aus Schlüsseldatei

Verschieben von xml-Datei aufgrund mehrerer Angaben aus externer Zuordnungsdatei

Hallo liebe Onliner,

nachdem ich das Forum rauf und runter durchsucht habe, und leider erst gerade mit Batch Programmierung begonnen habe, wende ich mich mit meinem Hilfeersuchen einmal an die fortgeschrittenen aus dem Forum:


Aus einem Abrechnungsprogramm erhalte ich pro Minute eine XML Datei "default.xml", die ich aufgrund von Bedingungen, die in einer Datei "Kostenstellen.txt" eingetragen ist, in Unterverzeichnisse z.B. 3080 für Kostenstelle 3080 verschieben möchte. Alles, was nicht sicher einer Kostenstelle zugeordnet werden kann, soll in einen Ordner c:\Rest geschoben werden


Kostenstellen.txt

"Keller-Stübchen"; x=230-240; y=700-801; c:\3080
"Keller - Stuebchen"; x=230-240; y=700-801; c:\3080
"Bar-Raum"; x=123-240; y=100-151; C:\2060
(...)

Legende:
"Suchtext";valider Range für coordx;valider Range für coordy; Zielverzeichnis


eintreffende XML Dateien "c:\Data\Default.xml" mit foldendem Inhalten

<roomiD Coordx="225" Coordy="856">"Keller-Stübchen"</roomid>
<roomiD Coordx="225" Coordy="856">"keller-stuebchen"</roomid>
<roomiD Coordx="225" Coordy="856">"Barraum"</roomid>
<roomiD Coordx="235" Coordy="456">"Keller - Stübchen"</roomid>
(...)

Kiffelig wird es nun dadurch,
dass z.B. der Wert "Keller-Stübchen" in der xml-Datei zwar mehrfach auftauchen kann, aber immer von eindeutigen Werten für Coordx und Coordy begleitet wird und nur dann einer Kostenstelle zugeordnet werden darf, wenn wenigstens ein Vorkommen bezgl. beider Koordinaten im durch die Datei Kostenstellen.txt vorgegeben Range liegt.

Den Inhalt der Datei "Kostenstellen.txt" kann ich beeinflussen,
also z.B. auch für Umlaut-/Sonderzeichenvarienten, die in der XML-Datei vorkommen können, mehrere Einträge einstellen.

Die "Kostenstellen.txt" hat zwischen 50 und 60 Zeilen, die XML-Datei kann bis zu 500 Zeilen haben. Die XML Datei ist immer zunächst nach COORDX und dann nach COORDY soriert.


Gibt es eine Möglichkeit, die Zuordnung per Batch zu realisiern?
Bin für jede Idee dankbar.


Gruß
mispel

Content-Key: 85706

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

Printed on: April 27, 2024 at 05:04 o'clock

Member: bastla
bastla Apr 17, 2008 at 00:03:20 (UTC)
Goto Top
Hallo mispel und willkommen im Forum!

Auch wenn noch Fragen bzw Vorschläge offen bleiben, sollte der folgende Entwurf im Prinzip funktionieren:
@echo off & setlocal
set "XML=C:\default.xml"  
set "KStListe=C:\Kostenstellen.txt"  
set "Rest=C:\Rest"  

set Ziel=
for /f "usebackq tokens=1-2 delims=<>" %%i in ("%XML%") do (  
	for /f "tokens=3,5 delims== " %%x in ("%%i") do (  
		set "KSt=%%~j" & set "X=%%~x" & set "Y=%%~y" & call :ProcessLine  
	)
)
if not defined Ziel set "Ziel=%Rest%"  
echo move "%XML%" "%Ziel%\"  
goto :eof

:ProcessLine
if defined Ziel goto :eof
findstr /i "%KSt%" "%KStListe%">nul || goto :eof  

for /f "tokens=2-4 delims=; " %%i in ('findstr /i /c:"%KSt%" "%KStListe%"') do set "XRange=%%i" & set "YRange=%%j" & set "Ordner=%%k"  
for /f "tokens=2,3 delims==-" %%i in ("%XRange%") do set "XLow=%%i" & set "XHigh=%%j"  
for /f "tokens=2,3 delims==-" %%i in ("%YRange%") do set "YLow=%%i" & set "YHigh=%%j"  

if %X% lss %XLow% goto :CheckY
if %X% leq %XHigh% set "Ziel=%Ordner%" & goto :eof  
:CheckY
if %y% lss %YLow% goto :eof
if %Y% leq %YHigh% set "Ziel=%Ordner%"  
goto :eof
Eine wichtige Frage betrifft das Verschieben, das hier vorerst nur durch die Ausgabe des "move"-Befehls (wegen des "echo" davor) simuliert wird: Eigentlich sollte es doch sehr wahrscheinlich sein, dass im jeweils ermittelten Kostenstellen-Ordner bereits eine "default.xml" liegt - es kann dann wohl nicht das Ziel sein, diese einfach zu überschreiben?

Zur Gestaltung der Kostenstellen.txt noch einige Anmerkungen, welche für mehr Sicherheit sorgen bzw die Verabeitung beschleunigen könnten:
- Die Leerzeichen nach den ";" sind eher kontraproduktiv und sollten daher weggelassen werden.
- Aus "x=230-240" würde ich einfach "230;240" machen (da ja die Reihenfolge ohnehin vorgegeben ist), wodurch eine weitere Zerlegung (durch je eine "for"-Zeile) überflüssig würde.
- Die "Suchtexte" benötigen eigentlich keine umschließenden Anführungszeichen - durch letztere wird es schwieriger, die Suche auf den Zeilenanfang zu begrenzen (auch wenn es kaum eine Verwechslungsmöglichkeit mit Texten aus dem Rest der Zeile geben dürfte).
- Dass alle Schreibweisen (zB "Barraum" vs "Bar-Raum" oder "keller-stuebchen" mit und ohne Leerzeichen) abgedeckt sein sollten, wäre ebenfalls nochmals zu betonen.

Schließlich stellt sich noch die Frage, wie der Batch gestartet werden soll, bzw ob beabsichtigt ist, ihn immer im Hintergrund laufen zu lassen - in letzterem Falle wäre zumindest eine Warteschleife (bis wieder eine "default.xml" verfügbar ist) am Anfang sinnvoll.

Grüße
bastla
Member: mispel
mispel Apr 17, 2008 at 10:16:36 (UTC)
Goto Top
Hallo bastla,
sieht ja genial aus.. !!

Bin einwenig platt und noch in der Verstehenphase.. - (hätte ich mal in der Schule besser aufgepaßt face-wink)

Was das Verschieben der default.xml betrifft, habe ich unterschlagen zu sagen, daß ich watchdirectory als hotfolder-tool einsetze und damit die default.xml gleich wieder umbenenne bzw wegräume. (ist vielleicht unsportlich, das Tool hilft mir aber sehr)

Ich versuche gerade, deine Ratschläge bzgl. Leerzeichen und Koordinaten und der zweiten for-Zeile umzusetzen sowie Suchtexte wegen "" abzuändern und ändere gerade die Kostenstellen.txt.

Dazu darf ich dann vielleicht noch einmal fragen, wenn ich es gar nciht hinbekomme ..?


Gruß + Danke

mispel
Member: bastla
bastla Apr 17, 2008 at 10:30:44 (UTC)
Goto Top
Hallo mispel!
... noch in der Verstehenphase..
Sorry, zum Kommentieren war ich schon etwas zu müde ...

... ändere gerade die Kostenstellen.txt.
Zum Testen solltest Du noch die alte Version verwenden, da ich von der oben beschriebenen Struktur ausgegangen bin.
Wenn das Verschieben geklärt ist, bliebe noch die Frage nach dem Start ...

Dazu darf ich dann vielleicht noch einmal fragen, wenn ich es gar nciht hinbekomme ..?
Das ist durchaus der Sinn dieses Forums ... face-wink

Grüße
bastla

P.S.:
hätte ich mal in der Schule besser aufgepaßt face-wink
In Deiner Schule wurde tatsächlich gebatcht? face-wink
Member: mispel
mispel Apr 17, 2008 at 15:22:35 (UTC)
Goto Top
Hallo bastla,

irgendwie klappt es nich nicht so ganz..die if-Statements machen mir noch Probleme..

if %X% lss %XLow% goto :CheckY
if %X% leq %XHigh% set "Ziel=%Ordner%" & goto :eof
:CheckY
if %y% lss %YLow% goto :eof
if %Y% leq %YHigh% set "Ziel=%Ordner%"

nach meinem Verständnis müßte es irgendwie in die foldende Richtung gehen:


if %y% geq %YLow% set "ok=1"
if %Y% leq %YHigh% set "ok=1"
if %X% geq %XLow% set "ok=1"
if %X% leq %XHigh% set "ok=1"


if %ok% equ 1 set Ziel=%Ordner% else set "Ziel=" & set "ok="


..funktioniert aber auch nicht (Syntax..) und mein Hirn ist schon ein wenig matschig..


Grüße
mispel


P.S. ja damals in der Schule gab es mal eine Informatik AG, aber da hab ich lieber mit den Mädels geflirtet... face-wink
Member: bastla
bastla Apr 17, 2008 at 15:38:48 (UTC)
Goto Top
Hallo mispel!

Die Idee bei den Abfragen ist folgende:
if %X% lss %XLow% goto :CheckY
Wenn der X-Wert des Datensatzes unterhalb der Untergrenze lt Kostenstellendatei liegt, kann gleich mit der Überprüfung des Y-Wertes fortgesetzt werden (X passt sicher nicht).

if %X% leq %XHigh% set "Ziel=%Ordner%" & goto :eof  
Wenn der X-Wert <= Obergrenze (> Untergrenze ist er sicher, sonst wären wir nicht mehr hier), haben wir die richtige Kostenstelle gefunden, daher ausgelesenen Ordner als Ziel speichern und fertig. %Ziel% funktioniert gleichzeitig als Schalter - wenn die Variable einen Inhalt hat, konnte die Zuordnung vorgenommen werden.

Für den Y-Wert gelten die gleichen Überlegungen.

Die Reihenfolge kannst Du natürlich auch umkehren und mit der Überprüfung von Y beginnen.
Deine Idee mit dem Schalter "ok" würde daran scheitern, dass es schon genügte, dass der Y-Wert mindestens der Untergrenze entspricht - ab diesem Zeitpunkt wäre "ok" bereits 1 und würde sich nicht mehr ändern (auch, wenn die Y-Obergrenze überschritten wäre).

Spätestens aber ab der zweiten Abfrage muss dann "ok" den Wert 1 aufweisen (wenn nämlich vorher unter %YLow%, so jetzt sicher unter %YHigh%).

Grüße
bastla
Member: mispel
mispel Apr 17, 2008 at 16:09:01 (UTC)
Goto Top
Hallo bastla,

-vorweg erstmal vielen Dank für Deine Mühe - bin Dir wirklich sehr dankbar...-

das Problem ist, dass sowohl x als auch y gleichzeitig im Range sein müssen -
ein Wert reicht nicht.
Wahrscheinlich habe ich das in der abendlichen Ermüdung gestern nicht mehr so genau auf die Reihe bekommen.

So, wie ich es jetzt verstehe, gibt es in der ursprünglichen Version auch einen Move-Vorgang in ein KOST Verzeichnis, wenn nur der Y-Wert im Range ist. Wenn aber in der gesamten XML-Datei bei keinem Suchwort X und Y (gleichzeitig) in den jeweiligen Ranges für das Suchwort liegen, muß es in den Rest gehen.

Das Umdrehen von X und Y ist mehr aus Versehen beim Rumprobieren passiert.


Grüße
mispel
Member: bastla
bastla Apr 17, 2008 at 17:03:55 (UTC)
Goto Top
Hallo mispel!

Ich hatte
... wenn wenigstens ein Vorkommen bezgl. beider Koordinaten im durch die Datei Kostenstellen.txt vorgegeben Range liegt.
anders interpretiert - das "Vorkommen" bezieht sich demnach auf die Datensätze der XML-Datei.

Um beide Koordinaten zu erfassen, sähe der Auswertungsteil etwa so aus:
if %X% lss %XLow% goto :eof
if %X% gtr %XHigh% goto :eof
if %y% lss %YLow% goto :eof
if %Y% gtr %YHigh% goto :eof
set "Ziel=%Ordner%"  
goto :eof

Grüße
bastla