更新1:
我可以通过try / catch来解决这个问题,但是当我知道问题是什么时,我宁愿不使用这个方法:
try {
buildHTML.push( "<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + day.td[2].span[0].span.content + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>");
} catch(err) {
buildHTML.push( "<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td></td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>");
}
原始问题:
使用以下jsonp服务:
我使用以下脚本来捕获数据:
$(document).ready(function() {
get_bbc_weather();
function get_bbc_weather() {
$.ajax({
url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%20%3D%20%22http%3A%2F%2Fnews.bbc.co.uk%2Fweather%2Fforecast%2F4276%3F%26search%3Dgerrards%2520cross%26itemsPerPage%3D10%26region%3Dworld%26area%3DGerrards%2520Cross%22%20and%20xpath%3D'%2F%2Ftbody'&format=json&callback=cbfunc22&rand=" + Math.random(),
type: 'GET',
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'cbfunc22',
error: function(xhr, status, error) {
alert(xhr.responseText);
},
success: function(data) {
var buildHTML = [];
var weather = data.query.results.tbody.tr;
buildHTML.push("<tr><td>Day</td><td>Weather</td><td>Max<br />Day<br />(°C)</td><td>Min<br />Night<br />(°C)</td><td>Wind<br />(MPH)</td>");
for (var i = 0; i < weather.length; i++) {
var day = weather[i];
buildHTML.push( "<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + day.td[2].span[0].span.content + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>");
}
$('#divContent1').empty().append("<table>" + buildHTML.join("</tr>") + "</table>")
}
});
}
});
但是,在某一天的某个时间,day.td[2].span[0].span.content
变为null
。发生这种情况时,如何检测它并仅在第一天使用下一个temp min
部分?其余时间应继续使用temp max
部分。
答案 0 :(得分:5)
我可能会在这里陈述显而易见的事,但为什么不使用if语句呢?
if (day.td[2].span[0].span.content != null) {
buildHTML.push( "<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + day.td[2].span[0].span.content + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>");
}
else {
buildHTML.push( "<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td></td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>");
}
答案 1 :(得分:2)
如果您use the YQL console to examine the output you're getting,您会看到整个td
变为null
。这就是你收到错误的原因。
你应该这样做:
if (day.td[2] == null)
(或者你喜欢用条件输出的方式。)
碰巧看到它在英国的那个夜晚,所以我实际上得到了有问题的输出。但鉴于that page可以为您找到世界各地的天气预报,您可以轻松地在其他时区选择一个城市并使用它来测试它。
答案 2 :(得分:1)
我知道这比你想要的要多得多,但这确实是我解决这个问题的方式。
不是从Web服务中获取JSON,而是建议获取HTML(example request),因为您使用的是jQuery并且它提供了一个很好的搜索机制 - 而不是自己遍历结构并运行当结构发生变化时陷入困境。
这是我以与结构无关的方式生成您正在制作的同一个表的代码。我遗漏了所有的ajax部件,因为它们保持不变。这只是成功的处理程序。
function success(data) {
var
$data = $('<table></table>')
.html(data.results[0]),
$table = $(
'<table>' +
'<thead>' +
'<tr>' +
'<th>Day</th>' +
'<th>Weather</th>' +
'<th>Max<br />Day<br />(°C)</th>' +
'<th>Min<br />Night<br />(°C)</th>' +
'<th>Wind<br />(MPH)</th>' +
'</tr>' +
'</thead>' +
'<tbody></tbody>' +
'</table>'
),
$tbody = $table.find('tbody');
$data
.find('tr')
.each(function(index, tr){
var
$input = $(tr),
$output = $('<tr></tr>')
.appendTo($tbody),
selectors = [
'.slotname abbr',
'.summary p',
'.temp.max .cent',
'.temp.min .cent',
'.wind .mph'
],
i = selectors.length,
text,
$cell;
while (i--) {
$('<td></td>')
.text(
$input
.find(selectors[i])
.text()
)
.prependTo($output);
}
});
$('#divContent1')
.empty()
.append($table);
}
希望这有帮助!
答案 3 :(得分:1)
要使用同一天的最小温度,请更改此
day.td[2].span[0].span.content
到这个
(day.td[2].span[0].span.content == null ? day.td[3].span[0].span.content : day.td[2].span[0].span.content)
如果这仍然引发异常,您需要确定day.td[2].span[0].span.content
的哪一部分返回为空,即您可能需要检查day.td[2].span[0] == null
。
修改:要明确,您的陈述将如下所示:
buildHTML.push( "<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + (day.td[2].span[0].span.content == null ? day.td[3].span[0].span.content : day.td[2].span[0].span.content) + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" );
此外,如果您只想让该单元格为空(而不是使用最大临时值),请使用:
(day.td[2].span[0].span.content == null ? "" : day.td[2].span[0].span.content)
答案 4 :(得分:1)
您可以使用||
opreator将null值替换为其他值。我不确定你想要什么价值,但这会使用第二天的价值:
buildHTML.push(
"<tr>" +
"<td>" + day.td[0].div.abbr.content + "</td>" +
"<td><img src='" + day.td[1].div.div.img.src + "' /></td>" +
"<td>" + (day.td[2].span[0].span.content || weather[i+1].td[2].span[0].span.content) + "</td>" +
"<td>" + day.td[3].span[0].span.content + "</td>" +
"<td>" + day.td[4].span[0].span[1].content + "</td>"
);
答案 5 :(得分:1)
正如sJhonny所提到的,你只需要使用if语句。问题是你需要知道什么实际上是null,因为跟随指针经过空值后,任何地方都会给你一个错误。如果不知道您收到的数据的详细信息,您应该能够检查所有内容:
var td2 = "";
if ( day.td[2] != null && day.td[2].span != null && day.td[2].span.length > 0 && day.td[2].span[0] != null && day.td[2].span[0].span != null && day.td[2].span[0].span.content != null ) {
td2 = day.td[2].span[0].span.content;
}
buildHTML.push( "<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + td2 + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>");
当然,如果您知道哪个字段专门设置为null,则可以简化if语句。我不会担心使用try / catch,如果这使你的代码更清晰(在这种情况下,我认为我更喜欢try / catch,我自己)。无论哪种方式,您可能应该检查其他字段 - 您可以保护您的网站免受随机错误的影响,因为该Feed中某些其他数据字段恰好为空。