Php Simplexml_load_string()无法分析错误

Php Simplexml_load_string()无法分析错误,php,simplexml,google-weather-api,Php,Simplexml,Google Weather Api,我正在尝试加载并解析一个谷歌天气API响应(中文响应) 是API调用 // This code fails with the following error $xml = simplexml_load_file('http://www.google.com/ig/api?weather=11791&hl=zh-CN'); (!)警告:simplexml_load_string() [function.simplexml加载字符串]: 实体:第1行:解析器错误:输入 UTF-8不正确,请

我正在尝试加载并解析一个谷歌天气API响应(中文响应)

是API调用

// This code fails with the following error
$xml = simplexml_load_file('http://www.google.com/ig/api?weather=11791&hl=zh-CN');
(!)警告:simplexml_load_string() [function.simplexml加载字符串]: 实体:第1行:解析器错误:输入 UTF-8不正确,请指示编码 ! 字节:0xB6 0xE0 0xD4 0xC6英寸 第11行C:\htdocs\weather.php

为什么加载此响应失败

如何对响应进行编码/解码,以便
simplexml
正确加载响应

编辑:以下是代码和输出

<?php
$googleData = file_get_contents('http://www.google.com/ig/api?weather=11102&hl=zh-CN');
$xml = simplexml_load_string($googleData);

(!)警告:simplexml_load_string()
[函数.simplexml加载字符串]:^in
C:\htdocs\test4.php在第3行调用
堆栈
时间记忆功能位置1 0.0020314264{main}(
)..\test4.php:0
2 0.1535 317520 simplexml加载字符串
(字符串(1364))..\test4.php:3


更新:我可以重现问题。另外,当我输出原始XML提要时,Firefox自动嗅探字符集为“简体中文”。要么谷歌订阅源提供的数据不正确(简体中文而非UTF-8),要么它提供的数据不同,而不是在浏览器中获取的数据——Firefox中的内容类型标题清楚地显示
UTF-8

将来自简体中文(GB18030,这是Firefox提供给我的)的传入提要转换为UTF-8是可行的:

 $incoming = file_get_contents('http://www.google.com/ig/api?weather=11791&hl=zh-CN');
 $xml = iconv("GB18030", "utf-8", $incoming);
 $xml = simplexml_load_string($xml);

不过,它还不能解释或解决根本问题。我现在没有时间深入研究这件事,也许其他人有。在我看来,谷歌实际上提供的是错误的数据(这让我感到惊讶。我不知道他们会像我们这些凡人一样犯错误。:P)

这里的问题是,SimpleXML没有查看HTTP头来确定文档中使用的字符编码,只是假设它是UTF-8,即使Google的服务器确实将其宣传为UTF-8

Content-Type: text/xml; charset=GB2312
您可以编写一个函数,使用超级秘密魔术变量
$http\u response\u header
查看该报头,并相应地转换响应。诸如此类:

function sxe($url)
{   
    $xml = file_get_contents($url);
    foreach ($http_response_header as $header)
    {   
        if (preg_match('#^Content-Type: text/xml; charset=(.*)#i', $header, $m))
        {   
            switch (strtolower($m[1]))
            {   
                case 'utf-8':
                    // do nothing
                    break;

                case 'iso-8859-1':
                    $xml = utf8_encode($xml);
                    break;

                default:
                    $xml = iconv($m[1], 'utf-8', $xml);
            }
            break;
        }
    }

    return simplexml_load_string($xml);
}
刚从这里过来。 这似乎有效(我在网上找到的函数本身,只是稍微更新了一下)

header('Content-Type:text/html;charset=utf-8');
函数getWeather(){
$requestAddress=”http://www.google.com/ig/api?weather=11791&hl=zh-CN”;
//根据位置下载天气数据。
$xml\u str=file\u get\u contents($requestAddress,0);
$xml_str=preg_replace(“/(]*>)/”、“$1$2$3”、$xml_str);
$xml_str=iconv(“GB18030”,“utf-8”,“$xml_str”);
//解析XML
$xml=新的simplexmlement($xml_str,TRUE);
//循环XML
$count=0;
回声';
foreach($xml->weather as$item){
foreach($item->forecast\u条件为$new){
回音“\n”;
回显“icon['data']”。“alt=””$new->condition['data']”“/>
\n”; echo“$new->day of_of_week['data']。”
; 回声“低:”.$new->Low['data']”。“高:”.$new->High['data']”; 回显“\n\n”; } } 回声'; } getWeather();
这是我用php编写的用于解析Google Weather API的脚本

 <?php

function sxe($url)
{
$xml = file_get_contents($url);
foreach ($http_response_header as $header)
{
if (preg_match('#^Content-Type: text/xml; charset=(.*)#i', $header, $m))
{
switch (strtolower($m[1]))
{

case 'utf-8':
// do nothing
break;

case 'iso-8859-1':
$xml = utf8_encode($xml);
break;

default:
$xml = iconv($m[1], 'utf-8', $xml);
}
break;
}
}
return simplexml_load_string($xml);
}


$xml = simplexml_load_file('http://www.google.com/ig/api?weather=46360&h1=en-us');
$information = $xml->xpath("/xml_api_reply/weather/forecast_information");
$current = $xml->xpath("/xml_api_reply/weather/current_conditions");
$forecast = $xml->xpath("/xml_api_reply/weather/forecast_conditions");


print "<br><br><center><div style=\"border: 1px solid; background-color: #dddddd; background-image: url('http://mc-pdfd-live.dyndns.org/images/clouds.bmp'); width: 450\">";


print "<br><h3>";
print $information[0]->city['data'] . "&nbsp;" . $information[0]->unit_system['data'] . "&nbsp;" .     $information[0]->postal_code['data'];
print "</h3>";
print "<div style=\"border: 1px solid; width: 320px\">";
print "<table cellpadding=\"5px\"><tr><td><h4>";
print "Now";
print "<br><br>";
print "<img src=http://www.google.com" . $current[0]->icon['data'] . ">&nbsp;";
print "</h4></td><td><h4>";
print "<br><br>";
print "&nbsp;" . $current[0]->condition['data'] . "&nbsp;";
print "&nbsp;" . $current[0]->temp_f['data'] . "&nbsp;°F";
print "<br>";
print "&nbsp;" . $current[0]->wind_condition['data'];
print "<br>";
print "&nbsp;" . $current[0]->humidity['data'];
print "<h4></td></tr></table></div>";




print "<table cellpadding=\"5px\"><tr><td>";


print "<table cellpadding=\"5px\"><tr><td><h4>";
print "Today";
print "<br><br>";
print "<img src=http://www.google.com" . $forecast[0]->icon['data'] . ">&nbsp;";
print "</h4></td><td><h4>";
print "<br><br>";
print  $forecast[0]->condition['data'];
print "<br>";
print  "High&nbsp;" . $forecast[0]->high['data'] . "&nbsp;°F";
print "<br>";
print  "Low&nbsp;" . $forecast[0]->low['data'] . "&nbsp;°F";
print "</h4></td></tr></table>";

print "<table cellpadding=\"5px\"><tr><td><h4>";
print  $forecast[2]->day_of_week['data'];
print "<br><br>";
print "<img src=http://www.google.com" . $forecast[2]->icon['data'] . ">&nbsp;";
print "</h4></td><td><h4>";
print "<br><br>";
print  "&nbsp;" . $forecast[2]->condition['data'];
print "<br>";
print  "&nbsp;High&nbsp;" . $forecast[2]->high['data'] . "&nbsp;°F";
print "<br>";
print  "&nbsp;Low&nbsp;" . $forecast[2]->low['data'] . "&nbsp;°F";
print "</h4></td></tr></table>";


print "</td><td>";


print "<table cellpadding=\"5px\"><tr><td><h4>";
print  $forecast[1]->day_of_week['data'];
print "<br><br>";
print "<img src=http://www.google.com" . $forecast[1]->icon['data'] . ">&nbsp;";
print "</h4></td><td><h4>";
print "<br><br>";
print  "&nbsp;" . $forecast[1]->condition['data'];
print "<br>";
print  "&nbsp;High&nbsp;" . $forecast[1]->high['data'] . "&nbsp;°F";
print "<br>";
print  "&nbsp;Low&nbsp;" . $forecast[1]->low['data'] . "&nbsp;°F";
print "</h4></td></tr></table>";

print "<table cellpadding=\"5px\"><tr><td><h4>";
print  $forecast[3]->day_of_week['data'];
print "<br><br>";
print "<img src=http://www.google.com" . $forecast[3]->icon['data'] . ">&nbsp;";
print "</h4></td><td><h4>";
print "<br><br>";
print  "&nbsp;" . $forecast[3]->condition['data'];
print "<br>";
print  "&nbsp;High&nbsp;" . $forecast[3]->high['data'] . "&nbsp;°F";
print "<br>";
print  "&nbsp;Low&nbsp;" . $forecast[3]->low['data'] . "&nbsp;°F";
print "</h4></td></tr></table>";


print "</td></tr></table>";


print "</div></center>";


?>
xpath(“/xml\u api\u reply/weather/forecast\u information”);
$current=$xml->xpath(“/xml\u api\u reply/weather/current\u conditions”);
$forecast=$xml->xpath(“/xml\u api\u reply/weather/forecast\u conditions”);
打印“

”; 打印“
”; 打印$information[0]->city['data']。“”.$information[0]->unit_system['data']。“”.$information[0]->邮政编码['data']; 打印“”; 打印“”; 打印“”; 打印“现在”; 打印“

”; 打印“图标[‘数据’”。"> "; 打印“”; 打印“

”; 打印“”$当前[0]->条件['data']。" "; 打印“”$当前[0]->temp_f['data']。“华氏度”; 打印“
”; 打印“”$当前[0]->风况[‘数据’]; 打印“
”; 打印“”$电流[0]->湿度[‘数据’]; 打印“”; 打印“”; 打印“”; 打印“今日”; 打印“

”; 打印“图标['data']。”>”; 打印“”; 打印“

”; 打印$forecast[0]->条件['data']; 打印“
”; 打印“高”。$forecast[0]->高['data']。“F”; 打印“
”; 打印“低”。$forecast[0]->Low['data']。“F”; 打印“”; 打印“”; 打印$forecast[2]->每周一天['data']; 打印“

”; 打印“图标[‘数据’”。"> "; 打印“”; 打印“

”; 打印“”$预测[2]->条件[‘数据’]; 打印“
”; 打印“高”$预测[2]->高['data']。“华氏度”; 打印“
”; 打印“低”$预测[2]->低[“数据”]。“华氏度”; 打印“”; 打印“”; 打印“”; 打印$forecast[1]->每周一天['data']; 打印“

”; 打印“图标['data']。”>”; 打印“”; 打印“

”; 打印“.$forecast[1]->条件['data']; 打印“
”; 打印“高”。$forecast[1]->高['data']。“F”; 打印“
”; 打印“低”。$forecast[1]->低['data']。“F”; 打印“”; 打印“”; 打印$forecast[3]->每周一天['data']; 打印“

”; 打印“图标[‘数据’”。"> "; 打印“”; 打印“

”; 打印“”$预测[3]->条件[‘数据’]; 打印“
”; 打印“高”$预测[3]->高[‘数据’]。“华氏度”; 打印“
”; 打印“低”$预测[3]->低[“数据”]。“华氏度”; 打印“”; 打印“”; 打印“”; ?>
尝试添加url查询参数eo=utf-8。在这种情况下,答案将完全是UTF-8编码。它帮助了我

http://www.google.com/ig/api?weather=?????&degree=??????&oe=utf-8&hl=es

Pekka:我已经尝试过了,xml看起来不错,但是当我将其传递给simplexml\u load\u string时,会出现大量解析错误:(.我是否需要将其转换为UTF-8字符串或其他内容?通过php加载会给您带来错误吗?@John稍等,我会尝试一下。@Pekka:谢谢!至少现在知道不是我的代码破坏了系统xD,我感觉很好。@John不客气。我可能会错,但看起来,这似乎实际上是错误的数据。事实上服务器确实使用GB2312字符集发布响应。因此,我只需将其复制粘贴到我的php中并更改变量,它就会识别类似于
&frasl;
的内容,这是一个
/
http://www.google.com/ig/api?weather=?????&degree=??????&oe=utf-8&hl=es