2012-08-09 45 views
2

我有以下腳本,它使用上的api hostip.info。該頁面根據IP地址解析用戶位置的xml讀數。在我的功能中,除了城市,一切都在運轉。preg match for xml輸出節點

preg_match("@<Hostip>(\s)*<gml:name>(.*?)</gml:name>@si",$xml,$city_match); 

我已縮小到我的preg_match錯了,但我不知道如何解決它。下面是一個示例XML輸出:http://api.hostip.info/?ip=12.215.42.19

<?php 
function getCountryCity() 
{ 
    if(isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) { 
     $ipAddr = $_SERVER['REMOTE_ADDR']; 
     // verify the IP address 
     ip2long($ipAddr)== -1 || ip2long($ipAddr) === false ? trigger_error("Invalid IP", E_USER_ERROR) : ""; 

     $ipDetail=array(); 
     // get the XML result from hostip.info 
     $xml = file_get_contents("http://api.hostip.info/?ip=".$ipAddr); 

     // get the city name inside the node <gml:name> and </gml:name> 
     preg_match("@<Hostip>(\s)*<gml:name>(.*?)</gml:name>@si",$xml,$city_match); 
     $ipDetail['city'] = $city_match[1]; 

     // get the country name inside the node <countryName> and </countryName> 
     preg_match("@<countryName>(.*?)</countryName>@si",$xml,$country_match); 
     $ipDetail['country'] = $country_match[1]; 

     // get the country name inside the node <countryName> and </countryName> 
     preg_match("@<countryAbbrev>(.*?)</countryAbbrev>@si",$xml,$cc_match); 
     $ipDetail['country_code'] = $cc_match[1]; 

     // return the array containing city, country and country code 
     return $ipDetail; 
    } else { 
     return false; 
    } 
} 

$ipDetail = getCountryCity(); 
$user_city = $ipDetail['city']; 
$user_country = $ipDetail['country']; 
$user_cc = $ipDetail['country_code']; 

echo $user_country.' ('.$user_cc.')'; 
echo $user_city; 

?> 
+1

有沒有理由不能使用XML解析器呢? – PeeHaa 2012-08-09 14:21:40

+0

這實際上是我需要一個xml解析器的唯一的東西,不確定它的值得安裝,如果這個愚蠢的preg替換是容易修復的 – Alex 2012-08-09 14:22:36

+0

你運行的是什麼PHP版本? – PeeHaa 2012-08-09 14:23:12

回答

0
function getCountryCity() { 
    if(isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) { 
     $user_ip = $_SERVER['REMOTE_ADDR']; 
     $response = file_get_contents('http://api.hostip.info/?ip='.$user_ip); 
     $user_details = array(); 
     $xml = new DOMDocument(); 
     $xml->loadXml($response); 
     $xpath = new DOMXpath($xml); 
     $path = '/HostipLookupResultSet/gml:featureMember/Hostip/'; 

     // create values for array 
     $ip = $xpath->evaluate($path . 'ip')->item(0)->nodeValue; 
     $city = $xpath->evaluate($path . 'gml:name')->item(0)->nodeValue; 
     $countryName = $xpath->evaluate($path . 'countryName')->item(0)->nodeValue; 
     $countryAbbrev = $xpath->evaluate($path . 'countryAbbrev')->item(0)->nodeValue; 

     // assign values to array 
     $user_details['ip'] = $ip; 
     $user_details['city'] = $city; 
     $user_details['countryName'] = $countryName; 
     $user_details['countryAbbrev'] = $countryAbbrev; 

     return $user_details; 
    } else { 
     return false; 
    } 
} 
1

XPATH是這種東西是夢想。谷歌「SimpleXML PHP教程」,如果這對你來說是新的。基本上:

$xml = new SimpleXMLElement($yourXML); 
$user_city = $xml->xpath('//gml:name/text()'); 
$user_country= $xml->xpath('//countryName/text()'); 
$cc= $xml->xpath('//countryAbbrev/text()'); 

我發現XPATH查詢比RegEx更容易編寫。

對不起,這並不能直接回答你的問題。試圖評論張貼但格式被完全搞砸了

+1

感謝我投你一票,但我提出了更多的解決方案,我可以使用 – Alex 2012-08-09 15:10:52

1
preg_match_all("@<gml:name>(.*?)</gml:name>@si",$xml,$city_match); 

只是刪除<Hostip>(\s)*和使用preg_match_all將採取所有的標籤。然後你可以選擇一個你需要的數組。

+0

有趣的解決方法 – Alex 2012-08-09 15:11:07