0

我愿意为我正在尝试做的事情提出建议,但结束游戏:使用 Windows 'wget' 命令从 weatherbug 下载天气 API 并获取该 xml 数据并将其存储到离线 xml 文件中,然后使用批处理脚本读取它.

我可以使用以下方法使其正常工作:

for /F "tokens=2 delims=><" %%i IN ('findstr /L "aws:temp>" wb_weather.xml') 
    do set cTemp=%%i

但只有 XML 的格式如下:

<aws:temp units="&deg;F">43.9</aws:temp>
<aws:temp-high units="&deg;F">62</aws:temp-high>
<aws:temp-low units="&deg;F">41</aws:temp-low>
<aws:temp-rate units="&deg;F/h">0</aws:temp-rate>

一旦我使用“wget”命令从网站上获取数据,数据看起来像这样(假设都是一行):

<aws:temp units="&deg;F">43.9</aws:temp><aws:temp-high units="&deg;F">62</aws:temp-high><aws:temp-low units="&deg;F">41</aws:temp-low><aws:temp-rate units="&deg;F/h">0</aws:temp-rate>

并且我上面的代码将无法正常工作。

我对整个 API 和批处理脚本编码非常陌生,但我使用批处理脚本,因为该项目的下一部分(分类)将需要批处理脚本格式。

4

3 回答 3

0
for /F "tokens=2 delims=><" %%i IN (
'type wb_weather.xml^|sed s/\x3e\x3c/\x3e\x0d\x0a\x3c/g^|findstr /L "aws:temp>"'
) DO ECHO %%i

可以为您工作 - 如果您可以使用 SED。

SED 替换><>[CR][LF]<呈现您认为有效的格式。

谷歌 GNU SED...

于 2013-04-02T04:25:43.180 回答
0

你写道:and the code I have from the above will not work correctly

请问,您对这一点做过测试吗?

您的代码指示从以“aws:temp>”结尾的唯一行中获取第二个标记。但是,如果其他行按照您上面显示的顺序与第一行组合,那么您想要的数据仍放置在包含前四行的新长行的第二个标记处。这意味着您的原始代码应该仍然可以正常工作!

如果您想要的数据放在另一行中,您只需更改“tokens =”数字即可将数据放在长行中的新位置。例如,“tokens=5”将获取第二行中的最高温度数据。

如果数据文件只包含四行的结果,那么你不需要使用findstr命令!

安东尼奥

于 2013-04-02T04:58:53.010 回答
0

如果您可以将 XML 解析为XML,而不仅仅是为了获取数据而必须刮掉的一堆垃圾,那么您将拥有更多的灵活性。为此,请允许我建议一个混合批处理/JScript 解决方案。

这具有额外的好处,使您能够通过XMLHTTP请求获取 XML 提要,消除对wget或类似的依赖。

将以下文件另存为weather.bat,根据需要修改API代码和邮政编码,试一试。

@if (@a==@b) @end /*

:: batch script portion

@echo off
setlocal

set "apicode=A1111111111"
set "zipcode=55555"
set "url=http://api.wxbug.net/getLiveWeatherRSS.aspx?ACode=%apicode%&zipCode=%zipcode%&UnitType=0&OutputType=1"

for /f "tokens=1*" %%a in ('cscript /nologo /e:jscript "%~f0" "%url%" ^|^| goto :EOF') do (
    set "%%a=%%b"
)

echo Temp: %awstemp%
echo High: %awstemphigh%
echo Low: %awstemplow%
echo Rate: %awstemprate%

echo;

:: show all variables beginning with aws and their values
set aws

goto :EOF

:: JScript portion */

function die(txt) {
    WSH.StdErr.WriteLine(txt.split(/\r?\n/).join(' '));
    WSH.Quit(1);
}

var x=new ActiveXObject("Microsoft.XMLHTTP");
x.open("GET",WSH.Arguments(0),true);
x.setRequestHeader('User-Agent','XMLHTTP/1.0');
x.send('');
var timeout = 60;
for (var i = 20 * timeout; x.readyState != 4 && i >= 0; i--) {
    if (!i) die("Timeout error.");
    WSH.Sleep(50)
};

if (!x.responseXML.hasChildNodes) die(x.responseText);

// Note: These dom nodes are appropriate for getLiveWeatherRSS.aspx and
// getLiveCompactWeatherRSS.aspx.  For parsing other feeds, change the
// root XPath node appropriately.
var dom = x.responseXML, dom = dom.selectSingleNode('//aws:ob') || dom.selectSingleNode('//aws:weather');

var out = [];
for (var i=0; i<dom.childNodes.length; i++) {
    if (dom.childNodes[i].hasChildNodes) {
        var item = dom.childNodes[i].nodeName.replace(/\W/g, '');
        var value = dom.childNodes[i].text;
        if (/rate$/.test(item) && value && value > 0) value = '+' + value;
        var units = dom.childNodes[i].getAttribute('units') || '';
        out.push(item + ' ' + value + units.replace('&deg;','°').replace('"',''));
    }
}
WSH.Echo(out.join('\n'));
于 2013-04-02T16:41:45.233 回答