Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
Shohreh
- Posts: 33
- Joined: 26 Feb 2020 08:05
#1
Post
by Shohreh » 06 Jun 2020 07:56
Hello,
I'd like to use a batch file to write an XML file, but without having to rely on the usual > sign because then, every sign must be escaped:
Code: Select all
@ECHO OFF
ECHO ^<?xml version="1.0" encoding="UTF-8"?^> > test.gpx
ECHO ^<gpx^> >> test.gpx
ECHO ^</gpx^> >> test.gpx
Can Windows be told to simply output every ECHO to a file from now on, eg. something like
Code: Select all
@ECHO OFF
OUTPUT test.gpx
ECHO <?xml version="1.0" encoding="UTF-8"?>
Thank you.
-
dbenham
- Expert
- Posts: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#2
Post
by dbenham » 06 Jun 2020 11:33
Code: Select all
@echo off
call :writeFile >output.txt
exit /b
:writeFile - All output from this routine will be written to output.txt
echo Line 1
echo Line 2
echo etc.
exit /b
Or, if you already have existingScript.bat that writes your desired output to the console (stdout), then from the console command line:
Dave Benham
-
Shohreh
- Posts: 33
- Joined: 26 Feb 2020 08:05
#3
Post
by Shohreh » 07 Jun 2020 02:36
Thanks, but it doesn't work on my Windows 7 computer:
Code: Select all
C:\>test2.bat >test2.xml
The syntax of the command is incorrect.
REM test2.bat
@ECHO OFF
ECHO <?xml version="1.0" encoding="UTF-8"?>
ECHO <gpx>
ECHO <trk>
ECHO <trkseg>
ECHO <trkpt lat="46.361004" lon="-1.180605">
ECHO </trkpt>
ECHO </trkseg>
ECHO </trk>
ECHO </gpx>
Code: Select all
C:\>test2.internal.print.bat
The syntax of the command is incorrect.
REM test2.internal.print.bat
@ECHO OFF
call :writeFile >test2.internal.print.xml
exit /b
:writeFile - All output from this routine will be written to test2.internal.print.xml
ECHO <?xml version="1.0" encoding="UTF-8"?>
ECHO <gpx>
ECHO <trk>
ECHO <trkseg>
ECHO <trkpt lat="46.361004" lon="-1.180605">
ECHO </trkpt>
ECHO </trkseg>
ECHO </trk>
ECHO </gpx>
exit /b
-
T3RRY
- Posts: 250
- Joined: 06 May 2020 10:14
#4
Post
by T3RRY » 07 Jun 2020 03:10
Another way to do this is to have the batch read itself and just escape the redirection characters in the command that outputs the xml file
Code: Select all
@Echo OFF
(For /F "Skip=2 Tokens=2 Delims=<>" %%A in (%~F0) Do Echo/^<%%A^>)>Output.xml
Goto :EOF
:<?xml version="1.0" encoding="UTF-8"?>
:<gpx>
:<trk>
:<trkseg>
:<trkpt lat="46.361004" lon="-1.180605">
:</trkpt>
:</trkseg>
:</trk>
:</gpx>
Last edited by
T3RRY on 07 Jun 2020 04:00, edited 1 time in total.
-
Shohreh
- Posts: 33
- Joined: 26 Feb 2020 08:05
#5
Post
by Shohreh » 07 Jun 2020 03:42
It almost works: The first line ("xm version") requires question marks, but for some reason, the line is missing in the output file. Is it due to the question mark?
Code: Select all
@ECHO OFF
if "%~1"=="" GOTO PARAM
(For %%A in (
"<?xml version="1.0" encoding="UTF-8"?>"
"<gpx>"
"<trk>"
"<trkseg>"
) Do Echo/%%~A)>output.gpx
REM From all input GPX files, read all track points into output.gpx
REM grep -Poh "(?s)<trkpt.+?</trkpt>" %1 >> output.gpx
(For %%A in (
"</trkseg>"
"</trk>"
"</gpx>"
) Do Echo/%%~A)>>output.gpx
GOTO END
:PARAM
echo Usage : %0 *.gpx
:END
Output:
Code: Select all
<gpx>
<trk>
<trkseg>
</trkseg>
</trk>
</gpx>
-
T3RRY
- Posts: 250
- Joined: 06 May 2020 10:14
#6
Post
by T3RRY » 07 Jun 2020 04:04
Sorry, for some reason I missed the question marks in my testing. The double quoting method does not work in that instance, the remaining component of my answer does work for lines containing question marks.
(Plain for loops treat question marks as a wildcard, hence why that method fails in that instance)
-
Shohreh
- Posts: 33
- Joined: 26 Feb 2020 08:05
#7
Post
by Shohreh » 07 Jun 2020 04:12
Can method #2 be modified somehow to include a call to grep in the middle, so that I can fetch track points from GPX files, insert them, and then append the end of the structure?
Code: Select all
@Echo OFF
(For /F "Skip=2 Tokens=2 Delims=<>" %%A in (%~F0) Do Echo/^<%%A^>)>Output.xml
Goto :EOF
:<?xml version="1.0" encoding="UTF-8"?>
:<gpx>
:<trk>
:<trkseg>
HERE, call to grep
:</trkseg>
:</trk>
:</gpx>
Or should I split the whole thing into three batch files (write the XML header, call grep, write the XML footer)?
-
T3RRY
- Posts: 250
- Joined: 06 May 2020 10:14
#8
Post
by T3RRY » 07 Jun 2020 04:25
Depending on how many lines of the script need to be modified, it's not to difficult to account for them. Data doesn't need to be hardcoded as in this example, A nested For loop can be used to refresh the needed data points for each usage (If the aim is to create multiple xml files, a filename convention will need to be used to create unique filenames)
Code: Select all
@Echo Off
Set "lat=46.361004"
Set "lon=-1.180605"
(For /F "Skip=4 Tokens=2 Delims=<>" %%A in (%~F0) Do IF "%%A" == "trkpt latlon" (Echo ^<trkpt lat="%lat%" lon="%lon%"^>) Else Echo/^<%%A^>)>Output.xml
:<?xml version="1.0" encoding="UTF-8"?>
:<gpx>
:<trk>
:<trkseg>
:<trkpt latlon>
:</trkpt>
:</trkseg>
:</trk>
:</gpx>
TYPE Output.xml
Last edited by
T3RRY on 07 Jun 2020 04:55, edited 3 times in total.
-
Shohreh
- Posts: 33
- Joined: 26 Feb 2020 08:05
#9
Post
by Shohreh » 07 Jun 2020 04:38
The problem is that an input file may contain tens of thousands of track points, ie. latitude + longtidude tuples.
Maybe I should just forget about cmd batch files for this task, and require installing a full scripting language like Perl or Python.
-
T3RRY
- Posts: 250
- Joined: 06 May 2020 10:14
#10
Post
by T3RRY » 07 Jun 2020 05:21
If the xml lines are highly variable, it may be easier to write them with the aid of a macro:
Code: Select all
@Echo Off
::: { Set environment state for Macro Definitions
Setlocal DisableDelayedExpansion
(Set LF=^
%= Above Empty lines Required =%)
Set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
Set xml.write=For %%n in (1 2) Do If %%n==2 (%\n%
For /F "Tokens=1,2 Delims={}" %%G in ("!xml_line!") Do (%\n%
^>^>"%%G.xml" Echo/^^^<%%H^^^>%\n%
)%\n%
Endlocal%\n%
) Else Setlocal EnableDelayedExpansion ^& Set xml_line=
::: End Macro Definition
Set "Outfile=xmlfilename"
Set "lat=46.361004"
Set "lon=-1.180605"
%xml.write%{%Outfile%}{?xml version="1.0" encoding="UTF-8"?}
%xml.write%{%Outfile%}{gpx}
%xml.write%{%Outfile%}{trk}
%xml.write%{%Outfile%}{trkseg}
%xml.write%{%Outfile%}{trkpt lat="!lat!" lon="!lon!"}
%xml.write%{%Outfile%}{/trkpt}
%xml.write%{%Outfile%}{/trkseg}
%xml.write%{%Outfile%}{/trk}
%xml.write%{%Outfile%}{/gpx}
TYPE %Outfile%.xml
Last edited by
T3RRY on 13 Jul 2020 09:00, edited 1 time in total.
-
Eureka!
- Posts: 137
- Joined: 25 Jul 2019 18:25
#12
Post
by Eureka! » 13 Jul 2020 03:44
Another approach:
Code: Select all
@echo off
setlocal
set OUTPUT=output.txt
set line1="<?xml version="1.0" encoding="UTF-8"?>"
set line2="<gpx>"
set line3="<trk>"
set line4="<trkseg>"
rem set line5="<trkpt lat="46.361004" lon="-1.180605">"
set line6="</trkseg>"
set line7="</trk>"
set line8="</gpx>"
(for /l %%x in (1,1,4) Do for /f "usebackq delims=" %%y in (`call echo %%line%%x%%`) DO echo %%~y) > "%OUTPUT%"
REM Insert code to add trkpt to output.txt
(for /l %%x in (6,1,8) Do for /f "usebackq delims=" %%y in (`call echo %%line%%x%%`) DO echo %%~y) >> "%OUTPUT%"
-
T3RRY
- Posts: 250
- Joined: 06 May 2020 10:14
#13
Post
by T3RRY » 13 Jul 2020 08:59
T3RRY wrote: ↑07 Jun 2020 05:21
If the xml lines are highly variable, it may be easier to write them with the aid of a macro:
Code: Select all
@Echo Off
::: { Set environment state for Macro Definitions
Setlocal DisableDelayedExpansion
(Set LF=^
%= Above Empty lines Required =%)
Set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
Set xml.write=For %%n in (1 2) Do If %%n==2 (%\n%
For /F "Tokens=1,2 Delims={}" %%G in ("!xml_line!") Do (%\n%
^>^>"%%G.xml" Echo/^^^<%%H^^^>%\n%
)%\n%
Endlocal%\n%
) Else Setlocal EnableDelayedExpansion ^& Set xml_line=
::: End Macro Definition
Set "Outfile=xmlfilename"
Set "lat=46.361004"
Set "lon=-1.180605"
%xml.write%{%Outfile%}{?xml version="1.0" encoding="UTF-8"?}
%xml.write%{%Outfile%}{gpx}
%xml.write%{%Outfile%}{trk}
%xml.write%{%Outfile%}{trkseg}
%xml.write%{%Outfile%}{trkpt lat="!lat!" lon="!lon!"}
%xml.write%{%Outfile%}{/trkpt}
%xml.write%{%Outfile%}{/trkseg}
%xml.write%{%Outfile%}{/trk}
%xml.write%{%Outfile%}{/gpx}
TYPE %Outfile%.xml