0

I'm querying Alexa to get a given url's ranking. The return is in XML. Most times Alexa returns XML containing the REACH & RANK values, though sometimes it doesn't. When it doesn't, the code below that grabs the value for RANK throws an error:

Fatal error: Call to a member function xpath() on a non-object...

// Alexa Ranking
$url = 'http://data.alexa.com/data?cli=10&dat=s&url=' . $final_site;
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_URL,$url); // set url to post to
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
curl_setopt($ch, CURLOPT_TIMEOUT, 4); // times out after 4s
$result = curl_exec($ch); // run the whole process
$xml = simplexml_load_string($result);
//Get reach node
$popularity = $xml->xpath("//REACH"); // <-- ERROR OCCURS HERE
//Get the rank attribute
$alexa_rank = (string)$popularity[0]['RANK'];

Like I mentioned above, sometimes the xml tree looks like:

<ALEXA VER="0.9" URL="venturengine.com/" HOME="0" AID="=">
<SD TITLE="A" FLAGS="" HOST="venturengine.com">
<LINKSIN NUM="8"/>
</SD>
<SD>
<POPULARITY URL="venturengine.com/" TEXT="8709770"/>
<REACH RANK="8474566"/>
</SD>
</ALEXA>

and sometimes it looks like:

<ALEXA VER="0.9" URL="store.guldfors.nu/" HOME="0" AID="=">
<SD TITLE="A" FLAGS="" HOST="store.guldfors.nu"></SD>
</ALEXA>

which doesn't have the REACH or RANK nodes/attributes.

Is there anyway to wrap the xpath such as:

if($xml->xpath("//REACH") === TRUE) {
  //Get reach node
  $popularity = $xml->xpath("//REACH"); // <-- ERROR OCCURS HERE
  //Get the rank attribute
  $alexa_rank = (string)$popularity[0]['RANK'];
}

I've tried the above, doesn't work.

George Ortiz
  • 199
  • 2
  • 4
  • 22

1 Answers1

0

I'm not sure of the exact syntax, but you might try counting the number of nodes in the target node set and seeing if it's greater than zero.

For example, count(//Reach) > 0

Another option appears to be to use boolean(//Reach)

See xpath find if node exists

Community
  • 1
  • 1
Steve
  • 543
  • 1
  • 6
  • 14
  • I tried wrapping the get node section with the following to count the number of nodes: `if(count($xml->xpath('//*') > 2)) {}` and it didn't work. The syntax might just be wrong though, not the idea. – George Ortiz Mar 29 '12 at 15:59
  • 1
    I don't know php. Does including the call to count inside the call to xpath -- e.g., $xml->xpath("count(//*) > 2") -- work? – Steve Mar 29 '12 at 20:20