I’m trying to parse some information from an XML file with a batch script and I have not been able to figure out how to rename the variable and keep the data intact. The output file is HTML which is what the device that is reading the data needs.
The batch file creates the HTML file just fine. The device is looking for Temperature: 75 and that is what it looks like in the file however if you check the file with a HTML editor the search name is included in the variable and the device can't use the data.
This is what I have been working on;
@echo off
start /b /WAIT %~dp0bitsadmin.exe /transfer "currentstats"
https://w1.weather.gov/xml/current_obs/KMGM.xml %~dp0Weather.xml
for %%a in (%~dp0Weather.xml) do (
for /f "tokens=* " %%b in ( ' type "%%a" ^|findstr /i "temp_f" ' ) do set tem1="%%b"
for /f "tokens=* " %%b in ( ' type "%%a" ^|findstr /i "relative_humidity" ' ) do set
hum1="%%b"
)
for /f "tokens=* delims=" %%P in ("<HTML>") do ( @echo %%P > %~dp0Weather.html)
for /f "tokens=* delims=" %%P in (%tem1%) do ( @echo Temperature: %%P >> %~dp0Weather.html)
for /f "tokens=* delims=" %%P in ("<BR />") do ( @echo %%P >> %~dp0Weather.html)
for /f "tokens=* delims=" %%P in (%hum1%) do ( @echo Humidity: %%P >> %~dp0Weather.html)
for /f "tokens=* delims=" %%P in ("</HTML>") do ( @echo %%P >> %~dp0Weather.html)
Data sample (from comments) Line breaks assumed.
<HTML> Temperature: <temp_f>75.0</temp_f> <BR />
Humidity: <relative_humidity>62</relative_humidity>
</HTML>
I Can’t figure how to remove the Left & Right pointing single angle quotation marks and what is between them so I end up with this.
<HTML> Temperature: 75.0 <BR />
Humidity: 62
</HTML>
CodePudding user response:
I would consider doing this using PowerShell instead. Using PowerShell you should be able to grab the data directly instead of downloading and reading an XML file. It also affords you the opportunity to output directly to HTML.
Example:
WeatherData.ps1
$weather_url = "https://w1.weather.gov/xml/current_obs/KMGM.xml"
$request = [System.Net.HttpWebRequest]::Create($weather_url)
$request.UserAgent = "MyApplication/v1.0 (http://foo.bar.baz; [email protected])"
$response = $request.GetResponse()
$doc = New-Object System.Xml.XmlDocument
$doc.Load($response.GetResponseStream())
$doc.current_observation | ConvertTo-HTML -As List @{Label = 'Temperature'; Expression = {[Int]$_.temp_f}}, @{Label = 'Humidity'; Expression = {$_.relative_humidity}} | Out-File ($MyInvocation.MyCommand.Path.DirectoryName 'weather.html')
To run that from a batch file, use this, (obviously changing %UserProfile%\Desktop\
as needed):
WeatherTest.cmd
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File "%UserProfile%\Desktop\WeatherData.ps1"
The output file weather.html
should be located in the cmd.exe instance's current directory.
Note: If you want the decimal temperature, as opposed to the whole integer, as I used above, change [Int]$_.temp_f
to just $_.temp_f
.
If I chose to do this using only a batch file, then I'd use the built-in curl.exe
utility, instead of bitsadmin.exe
:
WeatherData.cmd
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "_=" & For /F "Tokens=3 Delims=<>" %%G In ('%SystemRoot%\System32\curl.exe
"https://w1.weather.gov/xml/current_obs/KMGM.xml" -H "Accept: Application/XML"
2^>NUL ^| %SystemRoot%\System32\findstr.exe /IL "<temp_f> <relative_humidity>"
') Do @(If Not Defined _ (Set /P "=<HTML>Temperature: %%G<BR />" 0<NUL
Set "_=.") Else Set /P "=Humidity: %%G</HTML>" 0<NUL & Echo(
) 1>>"%~dp0weather.html"
CodePudding user response:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory and filename are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "filename1=%sourcedir%\q74092241.txt"
SET "omit="^<temp_f^>" "^</temp_f^>" "^<relative_humidity^>" "^</relative_humidity^>""
FOR /f "usebackqdelims=" %%e IN ("%filename1%") DO (
SET "line=%%e"
FOR %%y IN (%omit%) DO SET "line=!line:%%~y=!"
echo !line!
)
GOTO :EOF
I believe the key is to "escape" (turn off the special meaning) of >|< with a caret ^