Google Picasa API XML deserialization

喜欢而已 提交于 2020-01-05 04:51:04

问题


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&amp;RGB=0x000000&amp;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&amp;max-results=1000&amp;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&amp;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&amp;v=2' />
    <link rel='edit' type='application/atom+xml'
      href='https://picasaweb.google.com/data/entry/api/user/liz/albumid/albumID/1236820754876000?authkey=authKey&amp;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&amp;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>

回答1:


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:

[XmlType("generator", Namespace="http://www.w3.org/2005/Atom")]
public partial class FeedGenerator
{
    [XmlAttribute]
    public string version { get; set; }
    [XmlAttribute]
    public string uri { get; set; }
    [XmlText]
    public string text { get; set; }
}

[XmlType("category", Namespace="http://www.w3.org/2005/Atom")]
public partial class FeedCategory
{
    [XmlAttribute]
    public string scheme { get; set; }
    [XmlAttribute]
    public string term { get; set; }
}

[XmlType("entry", Namespace="http://www.w3.org/2005/Atom")]
public partial class FeedEntry
{
    public FeedCategory category { get; set; }
    public string title { get; set; }
    public string summary { get; set; }
}

[XmlType("author", Namespace="http://www.w3.org/2005/Atom")]
public partial class FeedAuthor
{
    public string name { get; set; }
    public string uri { get; set; }
}

[XmlType("link", Namespace="http://www.w3.org/2005/Atom")]
public partial class FeedLink
{
    [XmlAttribute]
    public string rel { get; set; }
    [XmlAttribute]
    public string @type { get; set; }
    [XmlAttribute]
    public string href { get; set; }
}

[XmlType("feed", Namespace="http://www.w3.org/2005/Atom")]
[XmlRoot("feed", Namespace="http://www.w3.org/2005/Atom")]
public partial class FeedList
{
    public string id        { get;set; }
    public string title     { get;set; }
    public string icon      { get;set; }

    [XmlElement("link")]
    public FeedLink[] links      { get;set; }
    public FeedGenerator generator      { get;set; }

    [XmlElement(Namespace="http://a9.com/-/spec/opensearch/1.1/")]
    public int totalResults      { get;set; }

    [XmlElement("entry")]
    public FeedEntry[] entries { get; set; }
}

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 link elements or the entry elements, define an array, and decorate it with XmlElement as shown. The values inside the double-quotes are the element names used for each. Attributes in the XML get properties decorated with the XmlAttribute attribute 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 with XmlAttribute gets 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 XmlElement attribute on the property, or, for a complex type, the XmlType attribute 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 XmlElement or XmlAttribute attribute 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 property totalResults deserializes the openSearch:totalResults element, because I've provided the xmlns corresponding to openSearch.

To deserialize the text node of an xml element, use an XmlText attribute.

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



来源:https://stackoverflow.com/questions/7263822/google-picasa-api-xml-deserialization

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!