【问题标题】:Undefined namespace prefix未定义的命名空间前缀
【发布时间】:2016-07-19 14:17:00
【问题描述】:

我正在使用雅虎天气 API

$result = file_get_contents('https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Sarajevo%22)&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys');
$xml = simplexml_load_string($result);
//echo htmlspecialchars($result, ENT_QUOTES, 'UTF-8');
$xml->registerXPathNamespace('yweather', 'http://xml.weather.yahoo.com/ns/rss/1.0');
    $weather_location = $xml->channel->xpath('yweather:location');
    if(!empty($weather_location)){
        foreach($xml->channel->item as $item){
            
           $forecast = $item->xpath('yweather:forecast');    
           $time =  time();
           $wdate = strtotime($forecast[$i]['day']);
    
           echo "".(string)$wdate."";  // Wed       
           echo "<span><b>".(int)$forecast[$i]['high']."°</b>";// 8
           echo "&nbsp;".(int)$forecast[$i]['low']."°</span>"; // 19      
        }            
}

示例 XML:

<?xml version="1.0" encoding="UTF-8"?>
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
    yahoo:count="1" yahoo:created="2016-03-31T10:56:53Z" yahoo:lang="en-US">
    <results>
        <channel>
            <yweather:units
                xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                distance="mi" pressure="in" speed="mph" temperature="F"/>
            <title>Yahoo! Weather - Sarajevo, Federacija Bosne I Hercegovine, BA</title>
            <link>http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-943828/</link>
            <description>Yahoo! Weather for Sarajevo, Federacija Bosne I Hercegovine, BA</description>
            <language>en-us</language>
            <lastBuildDate>Thu, 31 Mar 2016 12:56 PM CEST</lastBuildDate>
            <ttl>60</ttl>
            <yweather:location
                xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                city="Sarajevo" country="Bosnia and Herzegovina" region=" Federacija Bosne I Hercegovine"/>
            <yweather:wind
                xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                chill="70" direction="270" speed="4"/>
            <yweather:atmosphere
                xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                humidity="43" pressure="922.0" rising="0" visibility="16.1"/>
            <yweather:astronomy
                xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                sunrise="6:27 am" sunset="7:14 pm"/>
            <image>
                <title>Yahoo! Weather</title>
                <width>142</width>
                <height>18</height>
                <link>http://weather.yahoo.com</link>
                <url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>
            </image>
            <item>
                <title>Conditions for Sarajevo, Federacija Bosne I Hercegovine, BA at 12:00 PM CEST</title>
                <geo:lat xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">43.853161</geo:lat>
                <geo:long xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">18.38493</geo:long>
                <link>http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-943828/</link>
                <pubDate>Thu, 31 Mar 2016 12:00 PM CEST</pubDate>
                <yweather:condition
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="32" date="Thu, 31 Mar 2016 12:00 PM CEST"
                    temp="69" text="Sunny"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="30" date="31 Mar 2016" day="Thu" high="70"
                    low="41" text="Partly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="28" date="01 Apr 2016" day="Fri" high="72"
                    low="50" text="Mostly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="30" date="02 Apr 2016" day="Sat" high="68"
                    low="44" text="Partly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="30" date="03 Apr 2016" day="Sun" high="69"
                    low="45" text="Partly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="30" date="04 Apr 2016" day="Mon" high="69"
                    low="47" text="Partly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="30" date="05 Apr 2016" day="Tue" high="69"
                    low="47" text="Partly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="30" date="06 Apr 2016" day="Wed" high="69"
                    low="47" text="Partly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="28" date="07 Apr 2016" day="Thu" high="66"
                    low="49" text="Mostly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="28" date="08 Apr 2016" day="Fri" high="58"
                    low="50" text="Mostly Cloudy"/>
                <yweather:forecast
                    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
                    code="28" date="09 Apr 2016" day="Sat" high="58"
                    low="47" text="Mostly Cloudy"/>
                <description>&lt;![CDATA[&lt;img src="http://l.yimg.com/a/i/us/we/52/32.gif"/&gt;
&lt;BR /&gt;
&lt;b&gt;Current Conditions:&lt;/b&gt;
&lt;BR /&gt;Sunny
&lt;BR /&gt;
&lt;BR /&gt;
&lt;b&gt;Forecast:&lt;/b&gt;
&lt;BR /&gt; Thu - Partly Cloudy. High: 70Low: 41
&lt;BR /&gt; Fri - Mostly Cloudy. High: 72Low: 50
&lt;BR /&gt; Sat - Partly Cloudy. High: 68Low: 44
&lt;BR /&gt; Sun - Partly Cloudy. High: 69Low: 45
&lt;BR /&gt; Mon - Partly Cloudy. High: 69Low: 47
&lt;BR /&gt;
&lt;BR /&gt;
&lt;a href="http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-943828/"&gt;Full Forecast at Yahoo! Weather&lt;/a&gt;
&lt;BR /&gt;
&lt;BR /&gt;
(provided by &lt;a href="http://www.weather.com" &gt;The Weather Channel&lt;/a&gt;)
&lt;BR /&gt;
]]&gt;</description>
                <guid isPermaLink="false"/>
            </item>
        </channel>
    </results>
</query>

这是结果:

警告:SimpleXMLElement::xpath() [simplexmlelement.xpath]:第 8 行 /home/ugbosnia/public_html/blocks/weather/block.php 中未定义的命名空间前缀

警告:SimpleXMLElement::xpath() [simplexmlelement.xpath]: xmlXPathEval: 第 8 行 /home/ugbosnia/public_html/blocks/weather/block.php 中的评估失败

有什么建议吗?

【问题讨论】:

  • 实际上,使用 Xpath 处理 XML 非常容易。 @Ahmed-Gharamti 您能否添加一个小示例 XML 来提问。如果我调用 URL,我会得到一个与您的源不匹配的大部分空 XML。
  • 我添加了示例 XML

标签: php xml api xpath yahoo-weather-api


【解决方案1】:

可能是由于最近雅虎天气 API 发生了变化,如下所述:Making Yahoo Weather API request with OAuth 1

【讨论】:

    【解决方案2】:

    channel 不是文档元素的子节点。如果您阅读 XML,则文档元素是 query 和一个子 results。我建议将channel 存储在自己的变量中:

    $channel = $xml->results->channel;
    

    在使用 xpath() 方法之前,您必须在每个 SimpleXMLElement 上注册命名空间。在您的情况下,您在$xml 上注册它,但您没有在$channel$item 对象上注册它。 $xml = simplexml_load_string($result);

    $channel = $xml->results->channel;
    $channel->registerXPathNamespace('yweather', 'http://xml.weather.yahoo.com/ns/rss/1.0');
    
    $weather_location = $channel->xpath('yweather:location');
    if(!empty($weather_location)){
      foreach($channel->item as $item){
        $item->registerXPathNamespace('yweather', 'http://xml.weather.yahoo.com/ns/rss/1.0');
    
        $forecast = $item->xpath('yweather:forecast');    
        var_dump($forecast);     
      }      
    }
    

    输出:

    array(10) {
      [0]=>
      object(SimpleXMLElement)#8 (1) {
        ["@attributes"]=>
        array(6) {
          ["code"]=>
          string(2) "30"
          ["date"]=>
          string(11) "31 Mar 2016"
          ["day"]=>
          string(3) "Thu"
          ["high"]=>
          string(2) "70"
          ["low"]=>
          string(2) "41"
          ["text"]=>
          string(13) "Partly Cloudy"
        }
      }
      [1]=>
      object(SimpleXMLElement)#9 (1) {
       ...
    

    DOM 为 XPath 表达式使用单独的对象,因此您只需在该对象上注册命名空间:

    $document = new DOMDocument();
    $document->loadXml($result);
    $xpath = new DOMXpath($document);
    $xpath->registerNamespace('yweather', 'http://xml.weather.yahoo.com/ns/rss/1.0');
    
    $weather_location = $xpath->evaluate('//yweather:location');
    ...
    

    【讨论】:

    • 我试过这个,但我得到了`警告:在第 12 行的 /home/ugbosnia/public_html/blocks/weather/block.php 中为 foreach() 提供的参数无效``
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多