0

我必须解析一个包含各种命名空间的 xml 文件。
我已经注册了命名空间。

我的问题是我无法从cal:location块中提取数据。
例如,我需要 vcard:street-address 或 vcard:postal-code。

XML - 示例:

<channel>
<title>Veranstaltungen zum Thema Markt+Bauer vom 05.05.2011 bis 05.05.2012</title>
<link>https://www.wien.gv.at/vadb/internet/AdvPrSrv.asp?Layout=VAErgebnis_neu&amp;Type=S&amp;ganzjaehrig=ja</link>
<description>   Veranstaltungen zum Thema Markt+Bauer vom 05.05.2011 bis 05.05.2012     </description>
<lastBuildDate>Sa,05 Jän 2013 17:38:05 GMT</lastBuildDate>
<ManagingEditor>event@ma55.wien.gv.at</ManagingEditor>
<language>de-AT</language>
<dc:license>http://data.wien.gv.at/nutzungsbedingungen</dc:license>
<dc:rightsHolder>Stadt Wien</dc:rightsHolder>
<item>
<title>Bauernmarkt am Karmelitermarkt</title>
<link>https://www.wien.gv.at/vadb/internet/AdvPrSrv.asp?Layout=VAErgebnis_neu&amp;Type=K&amp;ID=256811&amp;return=</link>
<guid isPermaLink="false">https://www.wien.gv.at/vadb/internet/AdvPrSrv.asp?Layout=VAErgebnis_neu&amp;Type=K&amp;ID=256811&amp;return=</guid>
<description><![CDATA[
<p>07.01.2011 bis 31.12.2011<br />
08:00 bis 13:00<br />
Karmelitermarkt<br />http://www.wiener-maerkte.at</p>­<p>Spezieller Bauernmarkt mit     köstlichen naturreinen Produkten.</p>]]>
</description>
<category>Kulinarischer  Markt</category>
<dc:subject>Kulinarischer  Markt</dc:subject>
<cal:dtstart>2011-01-07T00:00:00+01:00</cal:dtstart>
<cal:dtend>2011-12-31T00:00:00+01:00</cal:dtend>
<cal:byday>Fr, Sa</cal:byday>
<cal:byhour>08</cal:byhour>
<cal:byminute>00</cal:byminute>
<cal:location>
    <vcard:fn>Karmelitermarkt</vcard:fn>
    <vcard:street-address>Haidgasse 1</vcard:street-address>
    <vcard:postal-code>1020</vcard:postal-code>
    <vcard:tel/>
    <vcard:fax/>
    <vcard:email>office@wiener-maerkte.at</vcard:email>
    <vcard:url>http://www.wiener-maerkte.at</vcard:url>
</cal:location>
<cal:organizer>
<vcard:fn>Wiener Einkaufsstraßen-Management</vcard:fn>
<vcard:street-address>Hietzinger Kai 133</vcard:street-address>
<vcard:postal-code>1130</vcard:postal-code>
<vcard:tel>0043-1/514 50-6700</vcard:tel>
<vcard:fax>0043-1/514 50-6749</vcard:fax>
<vcard:email/>
<vcard:url>http://www.einkaufsstrassen.at</vcard:url>
</cal:organizer>  
</item>
</channel>

我的 PHP - 代码:

<?php
function download_feed($path){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$path);
    curl_setopt($ch, CURLOPT_FAILONERROR,1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_TIMEOUT,15);
    $retValue = curl_exec($ch);
    curl_close($ch);
    return $retValue;
}
    $sXML = download_feed('xml - Example');
    $oXML = new SimpleXMLElement($sXML);

    foreach($oXML->channel->item as $oDocument){
    $title = $oDocument->title;
    $url = $oDocument->link;
    $namespaces = $oDocument->getNameSpaces(true);

    $cal = $oDocument->children($namespaces['cal']);
    $vcard = $cal->children($namespaces['vcard']);
    $dc = $oDocument->children($namespaces['dc']);
    $georss = $oDocument->children($namespaces['georss']);
    $byday = $cal->byday;

    //var_dump($vcard);
    $attrs = $oDocument->getElementsByTagName("vcard:fn");


     $streetAddress = $oDocument->{'cal:location'}->{'vcard:fn'};


    echo $title . "<br>" . $url . "<br>" . $byday. "<br>" . $streetAddress.   "<br><br>";
}               
?>
4

1 回答 1

0

您误解了该->children()方法的目的:它不会“注册”命名空间,而是选择它们以供立即使用。

所以要到达<cal:location>,你可以使用$oDocument->children($namespaces['cal'])->location<vcard:fn>里面就是$oDocument->children($namespaces['cal'])->location->children($namespaces['vcard'])->fn

从 PHP 5.2 开始,您还可以直接使用前缀,而不是查找它们的 URL,方法是给->children()方法一个额外的参数true$oDocument->children('cal', true)->location->children('vcard', true)->fn

于 2013-01-11T18:27:56.897 回答