Parsing XML data from hostip.info API service with PHP

If you ended up here, then you most likely experienced what I did in trying to figure out how to parse the XML data from the hostip.info web API service.

Basically, it is down to the namespaces that are not accessible by normal means.

Here is the basic XML response from a typical hostip.info call such as http://api.hostip.info/?ip=[IP-ADDRESS]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="ISO-8859-1" ?>
<HostipLookupResultSet version="1.0.1" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.hostip.info/api/hostip-1.0.1.xsd">
   <gml:description>This is the Hostip Lookup Service</gml:description>
   <gml:name>hostip</gml:name>
   <gml:boundedBy>
      <gml:Null>inapplicable</gml:Null>
   </gml:boundedBy>
   <gml:featureMember>
      <Hostip>
         <ip>12.215.42.19</ip>
         <gml:name>Sugar Grove, IL</gml:name>
         <countryName>UNITED STATES</countryName>
         <countryAbbrev>US</countryAbbrev>
         <!-- Co-ordinates are available as lng,lat -->
         <ipLocation>
            <gml:pointProperty>
               <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
                  <gml:coordinates>-88.4588,41.7696</gml:coordinates>
               </gml:Point>
            </gml:pointProperty>
         </ipLocation>
      </Hostip>
   </gml:featureMember>
</HostipLookupResultSet>


Here is a nice PHP function that will return all the important pieces for you:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function get_location($ip) {
	$content = @file_get_contents('http://api.hostip.info/?ip='.$ip);
	if ($content != FALSE) {
		$xml = new SimpleXmlElement($content);
		$coordinates = $xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->ipLocation->children('gml', TRUE)->pointProperty->Point->coordinates;
		$longlat = explode(',', $coordinates);
		$location['longitude'] = $longlat[0];
		$location['latitude'] = $longlat[1];		
                $location['citystate'] = '==>'.$xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->children('gml', TRUE)->name;
		$location['country'] =  '==>'.$xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->countryName;
		return $location;
	}
	else return false;
}

Here is the usage:

1
2
3
$ip = '12.215.42.19';
$location_info = get_location($ip);
var_dump($location_info);

The dump would look something like this:

array(4) {
  ["longitude"]=>
  string(8) "-74.9072"
  ["latitude"]=>
  string(7) "39.9499"
  ["citystate"]=>
  object(SimpleXMLElement)#5 (1) {
    [0]=>
    string(16) "Mount Laurel, NJ"
  }
  ["country"]=>
  object(SimpleXMLElement)#2 (1) {
    [0]=>
    string(13) "UNITED STATES"
  }
}

To access the longitude:
$location_info['longitude'];

To access the latitude:
$location_info['latitude'];

To access the city/state string:
$location_info['citystate'];

To access the country string:
$location_info['country'];

I did not bother to parse the city/state string because I’m not sure if this format is consistent for international addresses.

Anyway, I hope this code helps someone out there =)