David Flatley

Using e4x with XML Namespaces for Twitter search

by on Feb.01, 2011, under Actual RIA info, Adobe AIR, Adobe Flex, Cloud APIs

I was working on a component for a client that uses search.twitter.com to find all relevant tweets based on a query string recently and I noticed there’s a lot of other samples out there that use some hefty XML parsing code to sift the data rather than make life easy with e4x. The Twitter search API uses XML namespaces in its results, and it seemed that many other posts out on the intertoobs (can I coin this term?) were implying that it caused problems within AS3. Not true. Since I didn’t find a lot on the Twitter search topic specifically, a new blog post was born. The following is a quick and easy sample of how to use e4x in your XML results by using the given XML namespaces.

For this client’s component, I didn’t need to authenticate users, but rather, search for all public streams via a query string. If you take a look at the Twitter search API docs you can see the process pretty straightforward, it’s just using URL query strings to retrieve data . Generally, you can search for tweets:

  • containing a word
  • from a user
  • to a user
  • referencing a user
  • containing a hashtag
  • or combining any of these options together

There are also fancy things you can do to limit or filter results, but you can check them out in the API docs. When you receive a result from your search, you’ll see how Twitter makes use of namespaces in the XML. The first massive wad of nodes in the XML are metadata, but what we’re looking for in this example are the entry nodes that contain actual Tweets. If you dissect one closer, you’ll see the namespaces for google, openSearch, and “” (an empty string).


<entry xmlns:google="http://base.google.com/ns/1.0" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/Atom" xmlns:twitter="http://api.twitter.com/">
  <id>tag:search.twitter.com,2005:32244567415721984</id>
  <published>2011-02-01T01:11:18Z</published>
  <link type="text/html" rel="alternate" href="http://twitter.com/adobegroups/statuses/32244567415721984"/>
  <title>RT @adobegroups: Community Translation is now live on #AdobeTV! Learn how you can become a translator, or watch translated episodes http://adobe.ly/i0PFOv</title>
  <content type="html">RT &lt;a href="http://twitter.com/adobegroups"&gt;@adobegroups&lt;/a&gt;: Community Translation is now live on &lt;a href="http://search.twitter.com/search?q=%23AdobeTV" onclick="pageTracker._setCustomVar(2, 'result_type', 'recent', 3);pageTracker._trackPageview('/intra/hashtag/#AdobeTV');"&gt;#AdobeTV&lt;/a&gt;! Learn how you can become a translator, or watch translated episodes &lt;a href="http://adobe.ly/i0PFOv"&gt;http://&lt;b&gt;adobe&lt;/b&gt;.ly/i0PFOv&lt;/a&gt;</content>
  <updated>2011-02-01T01:11:18Z</updated>
  <link type="image/png" rel="image" href="http://a3.twimg.com/profile_images/312149750/alogo_normal.jpg"/>
  <twitter:geo/>
  <twitter:metadata>
    <twitter:result_type>recent</twitter:result_type>
  </twitter:metadata>
  <twitter:source>&lt;a href="http://www.tweetdeck.com" rel="nofollow"&gt;TweetDeck&lt;/a&gt;</twitter:source>
  <twitter:lang>en</twitter:lang>
  <author>
    <name>adobegroups (Adobe Groups)</name>
    <uri>http://twitter.com/adobegroups</uri>
  </author>
</entry>

In the entry node, the xmlns=”http://www.w3.org/2005/Atom” with no prefix points to the Atom syndication format specification. Atom is just another syndication format used for web feeds like RSS. Why Atom and not RSS you ask? Who knows? Some say Atom is better than RSS for this reason or that, some say we’re all made of tiny Atoms (not the same atoms, but still fascinating). Who’s to say really? I’m sure the developers at Twitter would say, but let’s not go off on a tangent here.

The XML namespace for the Atom specification in the Twitter search results does not use a prefix like xmlns:google for example. Take a look.


<entry xmlns:google="http://base.google.com/ns/1.0" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/Atom" xmlns:twitter="http://api.twitter.com/">

So into the Flex code, the first thing you’ll do is make use of your friend, the Namespace class, a.k.a the Namespace class to easily reference the data you’re looking for with e4x.

You’d typically make use of an HTTPService component for the search and set a result handler method to parse the XML returned from the search like so:


// script block
protected function handleResult(event:ResultEvent):void
{
	var x:XML = event.result as XML; // set the XML result
	var ns:Namespace = x.namespace(""); //  set the ns to an empty string like the result xml
	trace(ns); // outputs http://www.w3.org/2005/Atom set in the result xml from Twitter

	tweetsAC = new XMLList(x.ns::entry);

	for(var i:int = 0; i< tweetsAC.length(); i++){
		txtArea.htmlText += tweetsAC[i].ns::content.text() + "\n"; // notice use of the ns with double colon ::
		txtArea.htmlText += tweetsAC[i].ns::author.ns::name.text() + "\n\n";
	}

}

<fx:Declarations>
		<s:HTTPService id="twitterSearchService"
					   url="http://search.twitter.com/search.atom?q=adobe"
					   resultFormat="e4x"
					   result="handleResult(event)"
					   fault="handleFault(event)" />
	</fx:Declarations>

By making use of your namespace and referencing XML nodes with the double colon (::) you can do away with the infinite looping through nodes of old, and harness the power of e4x yet again. First, you set an actual Namespace variable in the code:


var ns:Namespace = x.namespace("");

Which enables you to reference any node as shown in the following:


trace(tweetsAC[i].ns::author.ns::name.text()); // traces the author's name from the <entry /> XML node

Now instead of looping for all of eternity to drill down into the XML, you can make use of e4x and pull the Tweets with few lines of code. The full source code is available for Flex 4 TwitterSearch.fxp.

:, , , ,

1 Comment for this entry

1 Trackback or Pingback for this entry

Leave a Reply


4 + two =

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!