{"<пользователь xmlns = ''> не ожидался.} Десериализация Twitter XML - PullRequest
177 голосов
/ 13 октября 2009

Я извлекаю XML из Twitter через OAuth.

Я делаю запрос к http://twitter.com/account/verify_credentials.xml,, который возвращает следующий XML:

<?xml version="1.0" encoding="UTF-8"?>
<user>
  <id>16434938</id>
  <name>Lloyd Sparkes</name>
  <screen_name>lloydsparkes</screen_name>
  <location>Hockley, Essex, UK</location>
  <description>Student</description>
  <profile_image_url>http://a3.twimg.com/profile_images/351849613/twitterProfilePhoto_normal.jpg</profile_image_url>
  <url>http://www.lloydsparkes.co.uk</url>
  <protected>false</protected>
  <followers_count>115</followers_count>
  <profile_background_color>9fdaf4</profile_background_color>
  <profile_text_color>000000</profile_text_color>
  <profile_link_color>220f7b</profile_link_color>
  <profile_sidebar_fill_color>FFF7CC</profile_sidebar_fill_color>
  <profile_sidebar_border_color>F2E195</profile_sidebar_border_color>
  <friends_count>87</friends_count>
  <created_at>Wed Sep 24 14:26:09 +0000 2008</created_at>
  <favourites_count>0</favourites_count>
  <utc_offset>0</utc_offset>
  <time_zone>London</time_zone>
  <profile_background_image_url>http://s.twimg.com/a/1255366924/images/themes/theme12/bg.gif</profile_background_image_url>
  <profile_background_tile>false</profile_background_tile>
  <statuses_count>1965</statuses_count>
  <notifications>false</notifications>
  <geo_enabled>false</geo_enabled>
  <verified>false</verified>
  <following>false</following>
  <status>
    <created_at>Mon Oct 12 19:23:47 +0000 2009</created_at>
    <id>4815268670</id>
    <text>&#187; @alexmuller your kidding? it should all be &quot;black tie&quot; dress code</text>
    <source>&lt;a href=&quot;http://code.google.com/p/wittytwitter/&quot; rel=&quot;nofollow&quot;&gt;Witty&lt;/a&gt;</source>
    <truncated>false</truncated>
    <in_reply_to_status_id>4815131457</in_reply_to_status_id>
    <in_reply_to_user_id>8645442</in_reply_to_user_id>
    <favorited>false</favorited>
    <in_reply_to_screen_name>alexmuller</in_reply_to_screen_name>
    <geo/>
  </status>
</user>

Я использую следующий код для десериализации:

    public User VerifyCredentials()
    {
        string url = "http://twitter.com/account/verify_credentials.xml";
        string xml = _oauth.oAuthWebRequestAsString(oAuthTwitter.Method.GET, url, null);

        XmlSerializer xs = new XmlSerializer(typeof(User),"");

        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));

        return (User)xs.Deserialize(ms);
    }

И у меня есть следующее для моего User класса:

 [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class User
{

    [XmlElement(ElementName = "id")]       
    public long Id { get; set; }

    [XmlElement(ElementName = "name")] 
    public string Name { get; set; }

    [XmlElement(ElementName = "screen_name")]       
    public string ScreenName { get; set; }

    [XmlElement(ElementName = "location")]       
    public string Location { get; set; }

    [XmlElement(ElementName = "description")]      
    public string Description { get; set; }

    [XmlElement(ElementName = "profile_image_url")]      
    public string ProfileImageUrl { get; set; }

    [XmlElement(ElementName = "url")]       
    public string Url { get; set; }

    [XmlElement(ElementName = "protected")]      
    public bool Protected { get; set; }

    [XmlElement(ElementName = "followers_count")]      
    public int FollowerCount { get; set; }

    [XmlElement(ElementName = "profile_background_color")]       
    public string ProfileBackgroundColor { get; set; }

    [XmlElement(ElementName = "profile_text_color")]       
    public string ProfileTextColor { get; set; }

    [XmlElement(ElementName = "profile_link_color")]       
    public string ProfileLinkColor { get; set; }

    [XmlElement(ElementName = "profile_sidebar_fill_color")]       
    public string ProfileSidebarFillColor { get; set; }

    [XmlElement(ElementName = "profile_sidebar_border_color")]      
    public string ProfileSidebarBorderColor { get; set; }

    [XmlElement(ElementName = "friends_count")]     
    public int FriendsCount { get; set; }

    [XmlElement(ElementName = "created_at")]     
    public string CreatedAt { get; set; }

    [XmlElement(ElementName = "favourties_count")]      
    public int FavouritesCount { get; set; }

    [XmlElement(ElementName = "utc_offset")]      
    public int UtcOffset { get; set; }

    [XmlElement(ElementName = "time_zone")]       
    public string Timezone { get; set; }

    [XmlElement(ElementName = "profile_background_image_url")]        
    public string ProfileBackgroundImageUrl { get; set; }

    [XmlElement(ElementName = "profile_background_tile")]        
    public bool ProfileBackgroundTile { get; set; }

    [XmlElement(ElementName = "statuese_count")]        
    public int StatusesCount { get; set; }

    [XmlElement(ElementName = "notifications")]       
    public string Notifications { get; set; }

    [XmlElement(ElementName = "geo_enabled")]       
    public bool GeoEnabled { get; set; }

    [XmlElement(ElementName = "Verified")]        
    public bool Verified { get; set; }

    [XmlElement(ElementName = "following")]
    public string Following { get; set; }

    [XmlElement(ElementName = "status", IsNullable=true)]
    public Status CurrentStatus { get; set; }

}

Но при десериализации вышеуказанного XML приложение выдает следующее:

  • $ exception {"Ошибка в XML-документе (2, 2)."} System.Exception {System.InvalidOperationException}

  • InnerException {" не ожидалось."} System.Exception {System.InvalidOperationException}

Теперь я искал вокруг, и лучшее решение, которое я могу найти, это добавить пустые пространства имен в сериализатор, когда вы сериализуете контент, но я не сериализую его, поэтому я не могу.

У меня также есть код для получения статусов, который отлично работает.

Так может кто-нибудь объяснить мне, почему происходит ошибка? А также возможное решение?

Заранее спасибо.

Ответы [ 11 ]

221 голосов
/ 13 октября 2009

Украсьте вашу корневую сущность атрибутом XmlRoot, который будет использоваться во время компиляции.

[XmlRoot(Namespace = "www.contoso.com", ElementName = "MyGroupName", DataType = "string", IsNullable=true)]

Или укажите корневой атрибут при сериализации во время выполнения.

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "user";
// xRoot.Namespace = "http://www.cpandl.com";
xRoot.IsNullable = true;

XmlSerializer xs = new XmlSerializer(typeof(User),xRoot);
126 голосов
/ 21 января 2011

Еще проще просто добавить следующие аннотации в начало вашего класса:

[Serializable, XmlRoot("user")]
public partial class User
{
}
22 голосов
/ 07 марта 2013
XmlSerializer xs = new XmlSerializer(typeof(User), new XmlRootAttribute("yourRootName")); 
9 голосов
/ 04 апреля 2012

Сообщение об ошибке настолько расплывчато, для меня у меня был такой код:

var streamReader = new StreamReader(response.GetResponseStream());
var xmlSerializer = new XmlSerializer(typeof(aResponse));
theResponse = (bResponse) xmlSerializer.Deserialize(streamReader);

Обратите внимание, что xmlSerializer был создан с помощью aResponse, но при десериализации я случайно привел его к bResonse.

4 голосов
/ 28 сентября 2016

Самое простое и лучшее решение - просто использовать в вашем классе атрибут XMLRoot , который вы хотите десериализовать.

как:

[XmlRoot(ElementName = "YourPreferableNameHere")]
public class MyClass{
...
}

Также используйте следующую сборку :

using System.Xml.Serialization;
4 голосов
/ 16 марта 2010

Как говорит Джон Сондерс, проверьте, соответствуют ли имена классов / свойств заглавным буквам вашего XML. Если это не так, проблема также возникнет.

2 голосов
/ 09 июня 2016

Единственное, что сработало в моем случае - это использование кода Дэвида Валентина. Использование Root Attr. в классе Person не помогло.

У меня есть этот простой XML:

<?xml version="1.0"?>
<personList>
 <Person>
  <FirstName>AAAA</FirstName>
  <LastName>BBB</LastName>
 </Person>
 <Person>
  <FirstName>CCC</FirstName>
  <LastName>DDD</LastName>
 </Person>
</personList>

C # класс:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Сериализация кода C # из метода Main:

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "personList";
xRoot.IsNullable = true;
using (StreamReader reader = new StreamReader(xmlFilePath))
{
List<Person> result = (List<Person>)(new XmlSerializer(typeof(List<Person>), xRoot)).Deserialize(reader);
 int numOfPersons = result.Count;
}  
2 голосов
/ 09 февраля 2016

Моя проблема была в том, что один из моих элементов имел атрибут xmlns:

<?xml version="1.0" encoding="utf-8"?>
<RETS ReplyCode="0">
    <RETS-RESPONSE xmlns="blahblah">
        ...
    </RETS-RESPONSE>
</RETS>

Независимо от того, что я пробовал, атрибут xmlns, казалось, нарушал сериализатор, поэтому я удалил любой след xmlns = "..." из файла xml:

<?xml version="1.0" encoding="utf-8"?>
<RETS ReplyCode="0">
    <RETS-RESPONSE>
        ...
    </RETS-RESPONSE>
</RETS>

и вуаля! Все работало.

Теперь я анализирую xml-файл, чтобы удалить этот атрибут перед десериализацией. Не уверен, почему это работает, возможно, мой случай другой, поскольку элемент, содержащий атрибут xmlns, не является корневым элементом.

1 голос
/ 28 октября 2018

Все вышеперечисленное не работает для меня, но это было: Убедитесь, что имя корневого элемента класса точно , как в XML с учетом регистра .

1 голос
/ 20 октября 2016

Моя проблема заключалась в том, что корневой элемент на самом деле имеет xmlns = "abc123"

Так пришлось сделать XmlRoot ("elementname", NameSpace = "abc123")

...