Suchen u. Ersetzen von XML-Tags (fortlaufende Nummerierung) per Batch oder Tool
Hallo allerseits
Ich bin auf der Suche nach einer Batchverarbeitung oder einem Tool, welches zum einen bestehende XML-Tags findet und diese so anpasst, dass von einem Startzähler aus ein Wert immer fortlaufend aufnummeriert wird.
Die XML-Datei sieht in etwa wie folgt aus:
Der Aufbau der Mitarbeiternummer ist nicht regelmässig. Nun will ich alle XML-Tags mit <Mitarbeiter-Nr.>*xxx*</Mitarbeiter-Nr.> ersetzen durch einen fortlaufenden XML-Tag z.B. ab dem Startzähler 100.
Das würde also im obigen Beispiel heissen, aus dem XML-Tag <Mitarbeiter-Nr.>105</Mitarbeiter-Nr.> wird <Mitarbeiter-Nr.>100</Mitarbeiter-Nr.>, aus <Mitarbeiter-Nr.>112</Mitarbeiter-Nr.> wird <Mitarbeiter-Nr.>101</Mitarbeiter-Nr.> und aus <Mitarbeiter-Nr.>115</Mitarbeiter-Nr.> wird <Mitarbeiter-Nr.>102</Mitarbeiter-Nr.>.
Mit dem untenstehenden Test-Skript, weiss ich leider nicht, wie die Variable gesetzt werden muss, damit alle XML-Tags mit <Mitarbeiter-Nr.>*xxx*</Mitarbeiter-Nr.> gefunden und ersetzt werden können oder ob dies über eine Variable überhaupt möglich ist.
Mit dem Tool "Useful File Utilities" und dem Plug-In "Batch Replacer" können zwar mit dem Suchparameter <Mitarbeiter-Nr.>#*#</Mitarbeiter-Nr.> alle Felder mutiert werden, doch für die fortlaufende Nummerierung habe ich leider keine Möglichkeit gefunden.
Vielen Dank im Voraus für Eure Tipps und Hilfestellung!
Beste Grüsse
DaMuchi
Ich bin auf der Suche nach einer Batchverarbeitung oder einem Tool, welches zum einen bestehende XML-Tags findet und diese so anpasst, dass von einem Startzähler aus ein Wert immer fortlaufend aufnummeriert wird.
Die XML-Datei sieht in etwa wie folgt aus:
<Connect>
<Task>
<Transaction>
<Mitarbeiter-Nr.>105</Mitarbeiter-Nr.>
...
</Transaction>
<Transaction>
<Mitarbeiter-Nr.>112</Mitarbeiter-Nr.>
...
</Transaction>
<Transaction>
<Mitarbeiter-Nr.>115</Mitarbeiter-Nr.>
...
</Transaction>
</Task>
<Connect>
Der Aufbau der Mitarbeiternummer ist nicht regelmässig. Nun will ich alle XML-Tags mit <Mitarbeiter-Nr.>*xxx*</Mitarbeiter-Nr.> ersetzen durch einen fortlaufenden XML-Tag z.B. ab dem Startzähler 100.
Das würde also im obigen Beispiel heissen, aus dem XML-Tag <Mitarbeiter-Nr.>105</Mitarbeiter-Nr.> wird <Mitarbeiter-Nr.>100</Mitarbeiter-Nr.>, aus <Mitarbeiter-Nr.>112</Mitarbeiter-Nr.> wird <Mitarbeiter-Nr.>101</Mitarbeiter-Nr.> und aus <Mitarbeiter-Nr.>115</Mitarbeiter-Nr.> wird <Mitarbeiter-Nr.>102</Mitarbeiter-Nr.>.
Mit dem untenstehenden Test-Skript, weiss ich leider nicht, wie die Variable gesetzt werden muss, damit alle XML-Tags mit <Mitarbeiter-Nr.>*xxx*</Mitarbeiter-Nr.> gefunden und ersetzt werden können oder ob dies über eine Variable überhaupt möglich ist.
@ECHO off
SETLOCAL enabledelayedexpansion
:: Suchen und Ersetzen von XML-Tags
SET quell_datei=D:\test1.txt
SET ziel_datei=D:\test2.txt
SET /A z=100
SET "suchen_nach=<Mitarbeiter-Nr.>100</Mitarbeiter-Nr.>"
SET "ersetzen_durch=<Mitarbeiter-Nr.>200</Mitarbeiter-Nr.>"
:: Loeschen der Ausgabedatei, falls sie (noch) existiert
IF EXIST %ziel_datei% (DEL /f %ziel_datei% 1>NUL 2>NUL)
:: Quell-Datei zeilenweise auslesen
:: und in Variable "zeile" schreiben
FOR /f "delims=" %%i IN ('FINDSTR . "%quell_datei%"') DO (
SET zeile=%%i&& CALL :ersetzen !zeile!
)
GOTO :weiter
:ersetzen
:: innerhalb der Variable "zeile"
:: den Inhalt der Variable "suchen_nach" suchen
:: und diese durch den Inhalt der Variable "ersetzen_durch" ersetzen
SET /A z="z+1"
SET zeile=!zeile:%suchen_nach%=%ersetzen_durch%
:: Inhalt der Variable "zeile" in die Ausgabedatei schreiben
IF [!zeile!] EQU (ECHO.>>%ziel_datei%) ELSE (ECHO !zeile!>>%ziel_datei%)
GOTO :eof
Mit dem Tool "Useful File Utilities" und dem Plug-In "Batch Replacer" können zwar mit dem Suchparameter <Mitarbeiter-Nr.>#*#</Mitarbeiter-Nr.> alle Felder mutiert werden, doch für die fortlaufende Nummerierung habe ich leider keine Möglichkeit gefunden.
Vielen Dank im Voraus für Eure Tipps und Hilfestellung!
Beste Grüsse
DaMuchi
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 128409
Url: https://administrator.de/forum/suchen-u-ersetzen-von-xml-tags-fortlaufende-nummerierung-per-batch-oder-tool-128409.html
Ausgedruckt am: 19.04.2025 um 15:04 Uhr
10 Kommentare
Neuester Kommentar
Hallo DaMuchi,
XML-Tags so zu maskieren, damit man mit ihnen vernünftig arbeiten kann, ist mit Batch immer ein Lotteriespiel. Habe hier auch Doppelmaskierungen vornehmen müssen, damit der FINDSTR Befehl das ganze gefressen hat.
Grüße
rubberman
XML-Tags so zu maskieren, damit man mit ihnen vernünftig arbeiten kann, ist mit Batch immer ein Lotteriespiel. Habe hier auch Doppelmaskierungen vornehmen müssen, damit der FINDSTR Befehl das ganze gefressen hat.
@echo off &setlocal
set quell_datei=D:\test1.txt
set ziel_datei=D:\test2.txt
set /a z=100
type nul>"%ziel_datei%"
for /f "delims=: tokens=1*" %%i in ('findstr /n "^" "%quell_datei%"') do set "Zeile=%%j" &call :sub
pause
goto :eof
:sub
if not defined Zeile (
>>"%ziel_datei%" echo.
goto :eof
)
set "Zeile=%Zeile:<=^^^<%"
set "Zeile=%Zeile:>=^^^>%"
set "Zeile=%Zeile:|=^^^|%"
set "Zeile=%Zeile:&=^^^&%"
echo %Zeile%|findstr /c:"Mitarbeiter-Nr">nul&&goto ersetzen
set Zeile=%Zeile%
>>"%ziel_datei%" echo %Zeile%
goto :eof
:ersetzen
set "Zeile= ^<Mitarbeiter-Nr.^>%z%^</Mitarbeiter-Nr.^>"
>>"%ziel_datei%" echo %Zeile%
set /a z+=1
goto :eof
Grüße
rubberman
Hallo DaMuchi und willkommen im Forum!
Wie rubberman schon gezeigt hat, ist für diese Problemstellung Batch zwar verwendbar, aber nicht unbedingt erste Wahl - daher als Alternative ein VBScript:
Zur (oberflächlichen) Kontrolle des Ergebnisses darf's dann wieder Batch sein:
(oder per "
Grüße
bastla
Wie rubberman schon gezeigt hat, ist für diese Problemstellung Batch zwar verwendbar, aber nicht unbedingt erste Wahl - daher als Alternative ein VBScript:
Ein = "D:\test1.txt"
Aus = "D:\test2.txt"
'Suchbegriff im RegEx-Format, daher: Punkt maskieren und zu ersetzenden Teil (=Nummer) in Klammern setzen
Such = "<Mitarbeiter-Nr\.>(\d+)</Mitarbeiter-Nr\.>"
N = 100 'Startwert für neue Nummerierung
Set fso = CreateObject("Scripting.FileSystemObject")
T1 = fso.OpenTextFile(Ein).ReadAll
Set rE = New RegExp
rE.Pattern = Such
rE.IgnoreCase = True
rE.Global = True
SP = 1 'Startposition im String
For Each M In rE.Execute(T1)
P = M.FirstIndex + M.Length + 1 'Endposition des die Fundstelle enthaltenden Teilstrings
'im gefundenen Teilstring (des Originaltextes) die bisherige Nummer ersetzen und zum neuen Text hinzufügen
T2 = T2 & Replace(Mid(T1, SP, P - SP), M.SubMatches(0), N, 1, 1)
N = N + 1
SP = P 'Startposition = vorige Endposition
Next
T2 = T2 & Mid(T1, SP) 'den Teil nach der letzten Fundstelle auch noch mitnehmen
fso.CreateTextFile(Aus, True).Write T2
Zur (oberflächlichen) Kontrolle des Ergebnisses darf's dann wieder Batch sein:
findstr /v /g:D:\test2.txt D:\test1.txt
findstr /v /g:D:\test1.txt D:\test2.txt
fc
").Grüße
bastla

Hallo zusammen!
Hier noch ne VB-Script-Variante (*.vbs)
@bastla
Warum so kompliziert?
Gruß Dieter
Hier noch ne VB-Script-Variante (*.vbs)
Const StartNum = 100
Const eFile = "D:\Eingabe.Txt"
Const aFile = "D:\Ausgabe.Txt"
Const Tag1 = "<Mitarbeiter-Nr.>"
Const Tag2 = "</Mitarbeiter-Nr.>"
Dim RE, Fso, File, Text, Tag, i
Set RE = New RegExp: i = StartNum
Set Fso = CreateObject("Scripting.FileSystemObject")
With RE
.Global = True: .IgnoreCase = True: .Pattern = Tag1 & ".*" & Tag2
End With
Set File = Fso.OpenTextFile(eFile): Text = File.ReadAll: File.Close
For Each Tag In RE.Execute(Text)
Text = Replace(Text, Tag, Tag1 & i & Tag2): i = i + 1
Next
Set File = Fso.CreateTextFile(aFile): File.Write Text: File.Close
@bastla
Warum so kompliziert?
Gruß Dieter
@76109
Ein weiterer Unterschied zwischen unseren Scripts besteht übrigens im Suchbegriff: Ich hatte xxx als numerisch (aus mindestens einer und sonst auch nur Ziffern bestehend) interpretiert, bei Dir wird alles (und auch Nichts) zwischen den "Mitarbeiter-Nr."-Tags ersetzt - was benötigt wird, muss DaMuchi wissen.
(Die Ungenauigkeit hinsichtlich des Punktes bei "Mitarbeiter-Nr." - könnte in Deiner Fassung ein beliebiges Zeichen sein - dürfte übrigens kaum relevant sein.)
Grüße
bastla
Warum so kompliziert?
Da es doch schon etwas spät war, habe ich mich nicht um etwaiges Optimierungspotential gekümmert, sondern die Sicherheitsvariante (auch, da nicht klar war, ob die bisherigen Nummern alle die gleiche Länge wie die neuen Nummern haben) gewählt - damit es zB nicht passiert, dass (wie es bei Deiner Version vorkommen kann), ein bereits ersetzter Teil nochmals ersetzt wird (kannst Du nachvollziehen, wenn Du in der Testdatei anstelle von 115
den Wert 101
einsetzt ...Ein weiterer Unterschied zwischen unseren Scripts besteht übrigens im Suchbegriff: Ich hatte xxx als numerisch (aus mindestens einer und sonst auch nur Ziffern bestehend) interpretiert, bei Dir wird alles (und auch Nichts) zwischen den "Mitarbeiter-Nr."-Tags ersetzt - was benötigt wird, muss DaMuchi wissen.
(Die Ungenauigkeit hinsichtlich des Punktes bei "Mitarbeiter-Nr." - könnte in Deiner Fassung ein beliebiges Zeichen sein - dürfte übrigens kaum relevant sein.)
Grüße
bastla

Hallo bastla!
Danke für die Erklärung!
Das es schon so spät war, hatte ich garnicht registriert
Im Gegensatz zu mir, hast Du natürlich wieder alle Eventualitäten berücksichtigt.
Bleibt die Frage, ob diese auch zu berücksichtigen sind. Das muss DaMuchi entscheiden.
Gruß Dieter
Danke für die Erklärung!
Das es schon so spät war, hatte ich garnicht registriert
Im Gegensatz zu mir, hast Du natürlich wieder alle Eventualitäten berücksichtigt.
Bleibt die Frage, ob diese auch zu berücksichtigen sind. Das muss DaMuchi entscheiden.
Gruß Dieter
Hallo DaMuchi!
Schön, dass wir helfen konnten.
Hinsichtlich des Problems bei "<AddressNumber>Zahl</AddressNumber>": Nur zur Sicherheit: Die entsprechende Code-Zeile sollte im Prinzip so aussehen:
Allerdings wird durch das Suchmuster "\d+" eine relativ "strenge" Überprüfung vorgenommen: Nur, wenn für "Zahl" ausschließlich Ziffern (und zwar mindestens eine) vorgefunden werden, erfolgt auch eine Ersetzung ("\d" steht dabei für eine Ziffer von 0 bis 9, das "+" verlangt, dass mindestens ein solches Zeichen vorkommt). Im Ansatz von didi1954 findest Du mit ".*" das "Gegenstück" - Bedeutung: Es kann, muss aber nicht (dafür sorgt der Stern) ein beliebiges Zeichen (symbolisiert durch den Punkt) als "Zahl" aufscheinen. Wenn Du daher auch mit dieser "lockeren" Suchbedingung leben kannst, sollte mit
auch die Ersetzung für diese Tags klappen.
Was "<Beneficiary>" und "<BeneficiaryCode>" angeht: Eigentlich sollte nur jeweils einer der beiden Suchbegriffe gefunden werden, also mit zB
nur ersterer - funktioniert bei mir übrigens auch (selbst mit
Als kurze Erklärung zum Ablauf des Scripts:
Nach dem Einlesen des gesamten Dateiinhaltes in eine Variable (T1) wird mit den oben angegebenen "Regulären Ausdrücken" nach den Fundstellen gesucht, wobei als Ergebnis sowohl die Position innerhalb des Strings (Zeichenanzahl vom Beginn weg gezählt) und die Länge des gefundenen Teiles (in Zeichen) als auch, ermöglicht durch die Klammern um den "Zahl"-Teil, als "SubMatch" die Zahl selbst zur Verfügung stehen.
Die Funde werden durch die "
Mit der Funktion
Am Ende wird die zweite Datei mit dem Inhalt der Variablen T2 erstellt.
Einen Literaturhinweis habe ich leider nicht anzubieten ...
Grüße
bastla
Schön, dass wir helfen konnten.
Hinsichtlich des Problems bei "<AddressNumber>Zahl</AddressNumber>": Nur zur Sicherheit: Die entsprechende Code-Zeile sollte im Prinzip so aussehen:
rE.Pattern = "<AddressNumber>(\d+)</AddressNumber>"
rE.Pattern = "<AddressNumber>(.*)</AddressNumber>"
Was "<Beneficiary>" und "<BeneficiaryCode>" angeht: Eigentlich sollte nur jeweils einer der beiden Suchbegriffe gefunden werden, also mit zB
rE.Pattern = "<Beneficiary>(\d+)</Beneficiary>"
(.*)
im Suchkriterium) ....Als kurze Erklärung zum Ablauf des Scripts:
Nach dem Einlesen des gesamten Dateiinhaltes in eine Variable (T1) wird mit den oben angegebenen "Regulären Ausdrücken" nach den Fundstellen gesucht, wobei als Ergebnis sowohl die Position innerhalb des Strings (Zeichenanzahl vom Beginn weg gezählt) und die Länge des gefundenen Teiles (in Zeichen) als auch, ermöglicht durch die Klammern um den "Zahl"-Teil, als "SubMatch" die Zahl selbst zur Verfügung stehen.
Die Funde werden durch die "
For-Next
"-Schleife nacheinander bearbeitet.Mit der Funktion
Mid()
kann dann das die Fundstelle beinhaltende Textstück aus T1 entnommen, die Zahl durch die laufende Nummer N ersetzt (siehe Replace()
und das Textstück einer zweiten Variablen (T2) hinzugefügt werden - mit dieser "Salamitaktik" wird immer nur der soeben benötigte Teil aus T1 übernommen, wodurch vor allem, wie schon oben angemerkt, verhindert werden soll, dass bereits "behandelte" Zahlen nochmals ersetzt werden. Da ich auch davon ausgegangen war, dass die Zahlen unterschiedlich lang sein könnten, konnte auch kein zeichenweiser Austausch der alten durch die neue Zahl erfolgen, sondern es musste die gesamte alte Zahl durch die neue Zahl ersetzt werden.Am Ende wird die zweite Datei mit dem Inhalt der Variablen T2 erstellt.
Einen Literaturhinweis habe ich leider nicht anzubieten ...
Grüße
bastla