使用批处理脚本从XML数据中读取标记

时间:2013-04-02 01:48:18

标签: api batch-file cmd wget

我愿意接受我想要做的事情,但结束游戏:使用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和批处理脚本编码都很陌生,但我使用批处理脚本,因为这个项目的下一部分(已分类)将需要批处理脚本格式。

3 个答案:

答案 0 :(得分: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]<,呈现您找到的格式。

Google GNU SED ...

答案 1 :(得分:0)

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

对不起,您是否对此进行了测试?

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

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

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

安东尼奥

答案 2 :(得分:0)

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

这样做的另一个好处是,您可以通过XMLHTTP请求获取XML Feed,从而消除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'));