【问题标题】:Simplexml_load_string() fail to parse errorSimplexml_load_string() 无法解析错误
【发布时间】:2011-02-23 08:45:05
【问题描述】:

我正在尝试加载解析 Google Weather API 响应(中文响应)。

Here 是 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-load-string]: 实体:第 1 行:解析器错误:输入 不是正确的UTF-8,表示编码 !字节:0xB6 0xE0 0xD4 0xC6 输入 C:\htdocs\weather.php 第 11 行

为什么加载此响应失败?

如何对响应进行编码/解码,以便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() [function.simplexml-load-string]: 实体:第 1 行:解析器错误:输入 不是正确的UTF-8,表示编码 !字节:0xB6 0xE0 0xD4 0xC6 输入 C:\htdocs\test4.php 第 3 行调用 堆 时间记忆功能位置 1 0.0020 314264 {main}( ) ..\test4.php:0 2 0.1535 317520 simplexml_load_string (字符串(1364))..\test4.php:3

( !) 警告:simplexml_load_string() [function.simplexml-load-string]: t_system 数据="SI"/>

( !) 警告:simplexml_load_string() [function.simplexml-load-string]: ^ in C:\htdocs\test4.php 第 3 行调用 堆 时间记忆功能位置 1 0.0020 314264 {main}( ) ..\test4.php:0 2 0.1535 317520 simplexml_load_string (字符串(1364))..\test4.php:3

【问题讨论】:

    标签: php simplexml google-weather-api


    【解决方案1】:

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

    Content-Type: text/xml; charset=GB2312
    

    您可以编写一个函数,使用超级秘密魔法变量$http_response_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);
    }
    

    【讨论】:

    • 所以我只是将它复制粘贴到我的 php 中并更改变量,它会识别像 &amp;frasl; 之类的东西,这是一个 /
    【解决方案2】:

    更新:我可以重现该问题。此外,当我输出原始 XML 提要时,Firefox 会自动将字符集嗅探为“简体中文”。要么 Google 提要提供不正确的数据(简体中文字符而不是 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)

    【讨论】:

    • Pekka:我试过了,xml 看起来不错,但是当我将它传递给 simplexml_load_string 时,我得到了大量的解析错误:(。我需要将它转换为 UTF-8 字符串还是什么?通过 php 加载它会给你一个错误吗?
    • @John 等一下,我试试看。
    • @Pekka:谢谢!至少现在我知道不是我的代码破坏了系统 xD,我感觉很好。
    • @John,不客气。我可能是错的,但看起来,这实际上是错误的数据。
    • 实际上,服务器确实使用 GB2312 字符集作为响应进行广告。
    【解决方案3】:

    刚刚遇到这个。 这似乎有效(我在网上找到的功能本身,只是更新了一下)。:

    header('Content-Type: text/html; charset=utf-8'); 
    
    
    function getWeather() {
    
    $requestAddress = "http://www.google.com/ig/api?weather=11791&hl=zh-CN";
    // Downloads weather data based on location.
    $xml_str = file_get_contents($requestAddress,0);
    $xml_str = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $xml_str); 
    
    $xml_str = iconv("GB18030", "utf-8", $xml_str);
    
    
    // Parses XML
    $xml = new SimplexmlElement($xml_str, TRUE);
    // Loops XML
    $count = 0;
    echo '<div id="weather">';
    
    foreach($xml->weather as $item) {
    
        foreach($item->forecast_conditions as $new) {
    
            echo "<div class=\"weatherIcon\">\n";
             echo "<img src='http://www.google.com/" .$new->icon['data'] . "'   alt='".$new->condition['data']."'/><br>\n";
            echo "<b>".$new->day_of_week['data']."</b><br>";
            echo "Low: ".$new->low['data']." &nbsp;High: ".$new->high['data']."<br>";
            echo "\n</div>\n";
            }
    
    }
    
    echo '</div>';
    }
    
    
    getWeather();
    

    【讨论】:

      【解决方案4】:

      这是我在 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>";
      
      
      ?>
      

      【讨论】:

        【解决方案5】:

        尝试在url查询参数中添加eo = utf-8。在这种情况下,答案将完全是 UTF-8 编码。它帮助了我。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-03
          • 2019-12-05
          • 1970-01-01
          • 2018-03-08
          • 2018-07-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多