如何获取simplexml中的下一个节点

时间:2013-05-23 19:47:46

标签: php xml simplexml

我正在使用yahoo weather 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;

2013年5月23日,我的流量为32美元和$ fdate

3 个答案:

答案 0 :(得分:1)

这是使用SimpleXML和Xpath的simple solution。只需将我的示例中的$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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

如果下一个节点意味着与当前节点同名的下一个节点,并且您通过父节点访问它们,就像您的情况一样:

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

然后,名为->forecast->的元素返回same-named-element-children-simplexml-container的 first 节点。这也可以写成->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对它们非常好,所以要经常使用它们。

希望这有帮助。