1

我正在使用 yahoo 天气 api,我想获取预报详细信息,但 XML 显示了两个这样的节点

<yweather:forecast day="Thu" date="23 May 2013" low="32" 
                   high="44" text="Clear" code="31"/>
<yweather:forecast day="Fri" date="24 May 2013" low="31" 
                   high="44" text="Sunny" code="32"/>

现在我如何选择第二个请帮助获取我正在使用此代码的节点,我只获取第一个节点值。

$myxml=new SimpleXMLElement("http://weather.yahooapis.com/forecastrss?w=$woeid[0]&u=c",NULL,TRUE);
$ab=$myxml->children();
$ad=$ab->channel->item->children('yweather',true)->forecast->attributes();

$fhigh=(string) $ad->high;
$flow=(string) $ad->low;
$ftemptype=(string) $ad->text;
$fdate=(string) $ad->date;

我得到 $flow 作为 32 和 $fdate 作为 2013 年 5 月 23 日

4

3 回答 3

1

这是一个使用 SimpleXML 和 Xpath的简单解决方案。只需将$myxml我示例中的变量替换为您的变量,就可以了:

<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
    <channel>
        <title>Yahoo! Weather - Sunnyvale, CA</title>
        <link>http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_c.html</link>
        <description>Yahoo! Weather for Sunnyvale, CA</description>
        <language>en-us</language>
        <lastBuildDate>Thu, 23 May 2013 12:55 pm PDT</lastBuildDate>
        <ttl>60</ttl>
        <yweather:location city="Sunnyvale" region="CA" country="United States" />
        <yweather:units temperature="C" distance="km" pressure="mb" speed="km/h" />
        <yweather:wind chill="17" direction="360" speed="22.53" />
        <yweather:atmosphere humidity="48" visibility="16.09" pressure="1016.6" rising="0" />
        <yweather:astronomy sunrise="5:53 am" sunset="8: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 Sunnyvale, CA at 12:55 pm PDT</title>
            <geo:lat>37.37</geo:lat>
            <geo:long>-122.04</geo:long>
            <link>http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_c.html</link>
            <pubDate>Thu, 23 May 2013 12:55 pm PDT</pubDate>
            <yweather:condition text="Fair" code="34" temp="17" date="Thu, 23 May 2013 12:55 pm PDT" />
            <description><![CDATA[<img src="http://l.yimg.com/a/i/us/we/52/34.gif"/><br />
<b>Current Conditions:</b><br />
Fair, 17 C<BR />
<BR /><b>Forecast:</b><BR />
Thu - Sunny. High: 19 Low: 9<br />
Fri - Sunny. High: 21 Low: 11<br />
<br />
<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_c.html">Full Forecast at Yahoo! Weather</a><BR/><BR/>
(provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/>]]>    </description>
            <yweather:forecast day="Thu" date="23 May 2013" low="9" high="19" text="Sunny" code="32" />
            <yweather:forecast day="Fri" date="24 May 2013" low="11" high="21" text="Sunny" code="32" />
            <guid isPermaLink="false">USCA1116_2013_05_24_7_00_PDT</guid>
        </item>
    </channel>
</rss>
XML;

$myxml = new SimpleXMLElement($xml);
$myxml->registerXPathNamespace('yweather', 'http://xml.weather.yahoo.com/ns/rss/1.0');
$secondForecast = $myxml->xpath('//yweather:forecast[2]');
$ad             = $secondForecast[0]->attributes();

$fhigh     = (string) $ad->high;
$flow      = (string) $ad->low;
$ftemptype = (string) $ad->text;
$fdate     = (string) $ad->date;

echo "High: {$fhigh} Low: {$flow} Type: {$ftemptype} Date: {$fdate}\n";

输出:

High: 21 Low: 11 Type: Sunny Date: 24 May 2013
于 2013-05-23T20:37:55.120 回答
0

可能最简单的做法是使用SimpleXMLIterator,它提供了一个简单的接口来遍历您的 xml 数据。您将创建迭代器,获取子代,然后使用next它从一个移动到下一个。

于 2013-05-23T20:07:06.363 回答
0

如果下一个节点是指与当前节点同名的下一个节点,并且您可以通过父节点访问它们,例如您的情况:

$ad = $ab->channel->item->children('yweather',true)->forecast->attributes();

然后 element-named->forecast->返回同名元素-children-simplexml-container的第一个节点。这也可以写成->forecast[0]->。因此,第二个元素是->forecast[1]->。是的,就这么简单。即使这看起来像一个数组,它不是一个,但它的工作方式与一个非常相似。所以 0 是第一个元素,1 是第二个元素,依此类推:

$url = "http://weather.yahooapis.com/forecastrss?w=$woeid[0]&u=c";
$xml = simplexml_load_file($url);

$items     = $xml->channel->item;
$forecasts = $items[0]->children('yweather', true)->forecast;

print_r($forecasts[0]->attributes()); # Day 1
print_r($forecasts[1]->attributes()); # Day 2

正如你在这个例子中看到的,我在很多地方都使用了数字索引。这使得代码更有说服力。

我给出的第二个提示是你使用更好的命名变量名。他们会帮助你很多,不要失去视线。而且你可以在 PHP 中浪费变量,PHP 对它们非常好,所以要大量使用它们。

希望这可以帮助。

于 2013-05-24T09:41:57.407 回答