Tuesday, 19 October 2010

Accessing Picasa's atom feed API from Spring's REST and XPath templates

Been swearing at my screen and Google's choice of atom based API for their Picasa web albums. Flickr's REST API took 10 seconds to work out. Picasa: days...


My problem:

Trying to parse album ids from Picasa's API: code.google.com/apis/picasaweb/docs/2.0/developers_guide_protocol.html#ListAlbum.


Source picasaResponse = restTemplate.getForObject( albumsURL, Source.class, parameters );

Jaxp13XPathTemplate xpathTemplate = new Jaxp13XPathTemplate();

Collection albumIds = xpathTemplate.evaluate("//entry",

      picasaResponse, new NodeMapper(){

   public Object mapNode(Node node, int i) throws DOMException {

      Element album = (Element) node;

      log.debug("IN NODE ALBUM");

      return null;

   }

}


This never worked. It should have I thought. Trying different combinations of "/entry", "/feed/entry", "//atom:entry", "/atom:feed/atom:entry", swapping with Jaxen, etc made no impact.


Then after some googlebashing and soulsearching I solved the problem.

The Xpath template needs a namespace to resolve the atom xml. So adding this solved the problem:


Source picasaResponse = restTemplate.getForObject( albumsURL, Source.class, parameters );

Jaxp13XPathTemplate xpathTemplate = new Jaxp13XPathTemplate();

Properties namespaces = new Properties();

namespaces.setProperty("atom",

   "http://www.w3.org/2005/Atom");

xpathTemplate.setNamespaces(namespaces);

Collection albumIds = xpathTemplate.evaluate("//atom:entry",

      picasaResponse, new NodeMapper(){

   public Object mapNode(Node node, int i) throws DOMException {

      Element album = (Element) node;

      log.debug("IN NODE ALBUM");

      return null;

   }

}




Ps. code simplified and not using bean injection etc for clarity.

2 comments:

Anonymous said...

How interesting. We have the same exact problem. I'm glad I've found your blog. The solution you provided solved my issue. Thanks a lot :)

Anonymous said...

Thank you for this post! I was struggling on this problem for a whole day unless I found this post.