Parsing FQL result

Facebook Query Language, or FQL, allows you to use a SQL-style interface to more easily query the same Facebook social data that you can access through other Facebook API methods (assuming your application has access!). Data returned for Facebook ActionScript Api are XML. You can access data via E4X after setting correct namespace. As for now (January 25, 2010), Facebook result defines xmlns=”http://api.facebook.com/1.0/” , but it may change in future, so lets make it dynamic…

Use e.g. extended FacebookLogger and add these lines

public function fql(query:String):void
{
	var call:FacebookCall = facebook.post(new FqlQuery(query));
	call.addEventListener(FacebookEvent.COMPLETE, fqlCallComplete);
}

private function fqlComplete(event:FacebookEvent):void
{
	var data:FacebookData = FacebookData(event.data);
	var xml:XML = XML(data.rawResult);
	var ns:Namespace = xml.namespace();
	default xml namespace = ns;
	
	var result:Array = [];
	for each(var user:XML in xml.user)
		result.push({uid:user.uid.toString(), name:user.name.toString()});

	default xml namespace = new Namespace("");	
	dispatchEvent(new ResultEvent(ResultEvent.RESULT, false, true, result));
}

Notice xml.namespace() line. This method returns Namespace object used in main node (“http://api.facebook.com/1.0/”), so we can define it as default xml namespace. If you do not set empty default namespace after you finish parsing this XML, it may throw some errors later in parsing another XMLs.

this is our fql query:

FB.fql("SELECT uid, name FROM user WHERE uid = XXX")

and data.rawResult contains following XML object

<?xml version="1.0" encoding="UTF-8"?>
<fql_query_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" list="true">
  <user>
    <uid>12345678</uid>
    <name>Some John Smith</name>
  </user>
  <user>
    <uid>12345679</uid>
    <name>Another John Smith</name>
  </user>...

Notice xmlns attribute in main node.

4 comments so far

  1. alex February 1, 2010 18:06

    i can’t get the xml to behave properly.

    i am doing as you say, here is my code:

    queries = { “user_stream”:”SELECT post_id, actor_id, target_id, message, attachment FROM stream WHERE source_id IN (SELECT target_id FROM connection WHERE source_id=” + 508510728 + ” AND is_following=1)”

    newsFeedCall = facebook.post(new FqlMultiquery(queries));
    newsFeedCall.addEventListener(FacebookEvent.COMPLETE, gotResult);

    private function gotResult(event : FacebookEvent) : void
    {
    var data : FacebookData = FacebookData(event.data);
    var xml : XML = new XML(data.rawResult);
    var ns : Namespace = xml.namespace();

    default xml namespace = ns;

    for each(var message:XML in xml.stream)
    {
    trace(message);
    }
    }

    I am having real problems accessing any child nodes of the fql returned xml by name, i’ve had to resort to using multiple .children() accessors which is less than ideal.

    Any ideas?

  2. Jozef Chúťka February 1, 2010 20:00

    Hi Alex,
    is there any purpose you call FqlMultiquery instead of just FqlQuery… it seems you only call one query. All results from FqlMultiquery comes in one xml string, each query has its own node (do not know it by heart but it is something like , you can debug your results)! So it corrupts your iteration.
    1. consider using FqlQuery instead of FqlMultiquery when calling only one fql
    2. or change iteration “for each(var message:XML in xml.stream)” to “for each(var message:XML in xml..stream)” or something even more specific
    3. or paste here xml result preview so I can help you

  3. alex February 2, 2010 12:33

    Hi Jozef,

    Thanks for replying so quickly.

    I am using the multi query to gather other information in additional queries, I just didn’t paste that in to the code I showed you as I felt it was irrelevant.

    Your tip about using the extra . has solved it. Now I feel stupid 😛

    Thank you very much for your help 🙂

  4. […] fqlComplete method, please read Parsing FQL result […]

Leave a comment

Please be polite and on topic. Your e-mail will never be published.