I’m currently working with the Google Picasa API trying to list albums.
The code to for OAuth 2.0 is written and working. I can get the XML list of albums without any issue. I have worked very little with XML in the past and I can’t get it to deserialize.
I tried to use the XSD.exe tool to generate a .xsd and then classes from that but I get an error right away: A column named ‘id’ already belongs to this DataTable.
I can’t figure out why because the second ID tag is nested in an other node. Can anyone put me in the right direction?
XML:
<?xml version='1.0' encoding='utf-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'
xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'
xmlns:exif='http://schemas.google.com/photos/exif/2007'
xmlns:geo='http://www.w3.org/2003/01/geo/wgs84_pos#'
xmlns:gml='http://www.opengis.net/gml'
xmlns:georss='http://www.georss.org/georss'
xmlns:batch='http://schemas.google.com/gdata/batch'
xmlns:media='http://search.yahoo.com/mrss/'
xmlns:gphoto='http://schemas.google.com/photos/2007'
xmlns:gd='http://schemas.google.com/g/2005'
gd:etag='W/"CkABRXY8fip7ImA9WxVVGE8."'>
<id>https://picasaweb.google.com/data/feed/api/user/liz</id>
<updated>2009-03-12T01:19:14.876Z</updated>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/photos/2007#user' />
<title>liz</title>
<subtitle></subtitle>
<icon>https://iconPath/liz.jpg</icon>
<link rel='http://schemas.google.com/g/2005#feed'
type='application/atom+xml'
href='https://picasaweb.google.com/data/feed/api/user/liz' />
<link rel='http://schemas.google.com/g/2005#post'
type='application/atom+xml'
href='https://picasaweb.google.com/data/feed/api/user/liz' />
<link rel='alternate' type='text/html'
href='http://picasaweb.google.com/liz' />
<link rel='http://schemas.google.com/photos/2007#slideshow'
type='application/x-shockwave-flash'
href='http://picasaweb.google.com/s/c/bin/slideshow.swf?host=picasaweb.google.com&RGB=0x000000&feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fliz%3Falt%3Drss' />
<link rel='self' type='application/atom+xml'
href='https://picasaweb.google.com/data/feed/api/user/liz?start-index=1&max-results=1000&v=2' />
<author>
<name>Liz</name>
<uri>http://picasaweb.google.com/liz</uri>
</author>
<generator version='1.00' uri='http://picasaweb.google.com/'>
Picasaweb</generator>
<openSearch:totalResults>1</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>1000</openSearch:itemsPerPage>
<gphoto:user>liz</gphoto:user>
<gphoto:nickname>Liz</gphoto:nickname>
<gphoto:thumbnail>
https://thumbnailPath/liz.jpg</gphoto:thumbnail>
<gphoto:quotalimit>1073741824</gphoto:quotalimit>
<gphoto:quotacurrent>32716</gphoto:quotacurrent>
<gphoto:maxPhotosPerAlbum>500</gphoto:maxPhotosPerAlbum>
<entry gd:etag='"RXY8fjVSLyp7ImA9WxVVGE8KQAE."'>
<id>https://picasaweb.google.com/data/entry/api/user/liz/albumid/albumID</id>
<published>2005-06-17T07:09:42.000Z</published>
<updated>2009-03-12T01:19:14.000Z</updated>
<app:edited xmlns:app='http://www.w3.org/2007/app'>
2009-03-12T01:19:14.000Z</app:edited>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/photos/2007#album' />
<title>lolcats</title>
<summary>Hilarious Felines</summary>
<rights>public</rights>
<link rel='http://schemas.google.com/g/2005#feed'
type='application/atom+xml'
href='https://picasaweb.google.com/data/feed/api/user/liz/albumid/albumID?authkey=authKey&v=2' />
<link rel='alternate' type='text/html'
href='http://picasaweb.google.com/lh/album/aFDUU2eJpMHZ1dP5TGaYHxtMTjNZETYmyPJy0liipFm0?authkey=authKey' />
<link rel='self' type='application/atom+xml'
href='https://picasaweb.google.com/data/entry/api/user/liz/albumid/albumID?authkey=authKey&v=2' />
<link rel='edit' type='application/atom+xml'
href='https://picasaweb.google.com/data/entry/api/user/liz/albumid/albumID/1236820754876000?authkey=authKey&v=2' />
<link rel='http://schemas.google.com/acl/2007#accessControlList'
type='application/atom+xml'
href='https://picasaweb.google.com/data/entry/api/user/liz/albumid/albumID/acl?authkey=authKey&v=2' />
<author>
<name>Liz</name>
<uri>http://picasaweb.google.com/liz</uri>
</author>
<gphoto:id>albumID</gphoto:id>
<gphoto:location>Mountain View, CA</gphoto:location>
<gphoto:access>public</gphoto:access>
<gphoto:timestamp>1118992182000</gphoto:timestamp>
<gphoto:numphotos>1</gphoto:numphotos>
<gphoto:numphotosremaining>499</gphoto:numphotosremaining>
<gphoto:bytesUsed>23044</gphoto:bytesUsed>
<gphoto:user>liz</gphoto:user>
<gphoto:nickname>Liz</gphoto:nickname>
<media:group>
<media:title type='plain'>lolcats</media:title>
<media:description type='plain'>Hilarious
Felines</media:description>
<media:keywords></media:keywords>
<media:content url='https://imagePath/Lolcats.jpg' type='image/jpeg' medium='image' />
<media:thumbnail url='https://thumbnailPath/Lolcats.jpg' height='160' width='160' />
<media:credit>Liz</media:credit>
</media:group>
</entry>
...more entries similar to the one above here...
</feed>
I don’t know why xsd.exe is not working. In my experience it’s good to give you a head start but it not foolproof in generating optimized C# classes for the XML document you want to serialize. There are other code-gen tools that do similar. XsdObjectGen is a free one, not sure if it is still around.
In my comment, I said On the other hand it’s pretty mechanical to hand-code your class to work with the Xml Serializer.
This partial example ought to get you started:
This code de-serializes just those elements in the FeedList class.
If you want additional elements, add them in. A text element can be deserialized as a property of a simple type, like a string, int, or DateTime. A complex element needs to be a property of a custom class, decorated with
XmlType.To deserialize a sequence of multiple elements, like the
linkelements or theentryelements, define an array, and decorate it withXmlElementas shown. The values inside the double-quotes are the element names used for each. Attributes in the XML get properties decorated with theXmlAttributeattribute in the C# code, and the value in the quotes is the attr name. No value means to map the attribute in the xml that has the same name as the property name, into the given property. (A property named “rel” in the C# code decorated withXmlAttributegets mapped to the xml attribute value with the name “rel” in the XML document)If you care about the elements from the other schema (like the opensearch schema, etc), you need to specify properties corresponding to the elements from those schema. Again, use custom classes for complex types in the XML; simple C# datatypes for simple (text only) elements in the XML. For a simple type, the
XmlElementattribute on the property, or, for a complex type, theXmlTypeattribute on the custom class, must specify the xmlns namespace for that element. You need not worry about the element prefix – the namespace is what is important. See the totalResults property as an example.When an
XmlElementorXmlAttributeattribute lacks an unlabeled string value, the element name or attribute name is assumed to be the name of the property itself. So in the above, the propertytotalResultsdeserializes theopenSearch:totalResultselement, because I’ve provided the xmlns corresponding to openSearch.To deserialize the text node of an xml element, use an
XmlTextattribute.Extend the example above and you should be able to deserialize everything you need to deserialize.
EDIT
But you may wanna use a library that is already built to do this.
http://code.google.com/p/google-gdata/updates/list