JosefZ may be correct in his comment - Your file will be overwritten by an empty temp.xml if input.xml is locked by another process. But the lock must be temporary, otherwise the COPY command will fail as well, and your original will be unchanged.
The only other potential reason I can think of is if your input.xml was already empty at the start of the process. But then an empty input.xml should be the expected result.
The following minimal change will prevent the lock problem. I preserved as much of your code as possible, except I reformatted the spacing and line breaks to better show the logic with all of those parentheses.
I put an extra set of parentheses around the 2nd loop, and conditionally MOVE and COPY the files only if the inner loop was successful. Otherwise I delete the temp file, and the original remains unchanged and the dated copy is not created. I also used MOVE instead of COPY followed by DEL.
Note that the 2ND FOR /F loop also returns failure if it was not able to read any lines, so the dated copy will not be created if input.xml starts out as empty. But if the <initialTransferReference>
line is not found, then no change is made, yet the dated copy will still be created.
@echo off
setlocal EnableDelayedExpansion
set dt=%date:~7,2%-%date:~4,2%-%date:~10,4%_%time:~0,2%-%time:~3,2%-%time:~6,2%
cd C:\test\inputFiles
(
for /F "delims=" %%a in ('findstr /I /L "<initialTransferReference>" input.xml') do (
set "line=%%a"
set "line=!line:*<initialTransferReference>=!"
for /F "delims=<" %%b in ("!line!") do (
set a=%%b
)
)
)
set /a newvalue=a+1
(
(
for /F "delims=" %%a in (input.xml) do (
set "line=%%a"
set "newLine=!line:initialTransferReference>=!"
if "!newLine!" neq "!line!" (
set "newLine=<initialTransferReference>%newvalue%</initialTransferReference>"
)
echo !newLine!
)
) > temp.xml
) && (
move /y temp.xml input.xml >nul
copy /y input.xml "C:\test\modifiedFile\input_%dt%.xml" >nul
) || del temp.xml 2>nul
Your code could be dramatically simplified. For example, you could easily do everything in one loop.
Also, your code is highly dependent on the format of the XML. It will fail if there are multiple tags on the <initialTransferReference>
line, or if the tag is split across multiple lines. It will also fail if the file contains !
.
A much more robust solution could be written with batch, but I wouldn't bother - it quickly becomes a complicated, arcane mess.
I propose you use my JREPL.BAT regular expression text processor instead :-)
JREPL.BAT is pure script (hybrid JScript/batch) that runs natively on any Windows machine from XP onward. The solution could be as simple as:
@echo off
setlocal
set dt=%date:~7,2%-%date:~4,2%-%date:~10,4%_%time:~0,2%-%time:~3,2%-%
call jrepl "\d+(?=\s*</initialTransferReference>)" "Number($0)+1" /j /m /f "C:\test\inputFiles\input.xml" /o - && copy /y "C:\test\inputFiles\input.xml" "C:\test\modifiedFile\input_%dt%.xml"
The above looks for a number that precedes the closing tag, and replaces it with the incremented value. It doesn't care if there additional tags on the line. It even allows the value and closing tag to be on separate lines.
The dated copy is only created if JREPL successfully modified the input.xml. It will not be created if input.xml was locked, or if it did not make any changes because no integer value was found before </initialTransferReference>
.
Like most regex XML "solutions", it is still possible to throw valid XML at it that can fail, but you would probably have to go out of your way to make it fail. It will most likely work with any real world data that you throw at it.
If you really want a robust solution, then you should use VBS, JScript, or PowerShell to properly parse and manipulate the XML.
I don't like how you derive your timestamp value because it is dependent on the date and time formats used by your locale. But that is an entirely different topic.
Last update in response to question in comment
You can use one more JREPL instead of XCOPY to append the date string to the Filename tag and write the output file in a single step. Note my use of line continuation to make the code easier to read.
@echo off
setlocal
set dt=%date:~7,2%-%date:~4,2%-%date:~10,4%_%time:~0,2%-%time:~3,2%-%
call jrepl "\d+(?=\s*</initialTransferReference>)" "Number($0)+1" /j /m /f "C:\test\inputFiles\input.xml" /o - && ^
call jrepl "(?=\s*</FileName>)" "_%dt%" /m /f "C:\test\inputFiles\input.xml" /o "C:\test\modifiedFile\input_%dt%.xml"