2009-10-12 9 views
136

tak Im ciągnięcie w pliku XML z Twittera za pośrednictwem OAuth{ "nie spodziewano <xmlns user = ''>.} Deserializacji Twitter XML

Więc robię wniosek do http://twitter.com/account/verify_credentials.xml

która zwraca następujące 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> 

Używam następujący kod do Deserialise

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); 
    } 

I Mam następujący mojej klasy użytkownika

[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; } 

} 

Ale kiedy jej deserialising powyższy Xml pojawia się następujący błąd rzucony

  • $ wyjątku { "Wystąpił błąd w dokumencie XML (2, 2 System.Exception). "} {System.Exception System.InvalidOperationException}

  • InnerException {" < xmlns user = '' > nie przewidywano. "} {System.InvalidOperationException}

Teraz szukałem i najlepsze rozwiązanie, jakie mogę znaleźć, to dodawanie pustych przestrzeni nazw do serializera, gdy serializuje się zawartość, ALE nie dokonuję serializacji, więc nie mogę.

Mam również kod do otrzymywania statusów, który działa dobrze.

Czy ktoś może mi wyjaśnić, co i dlaczego powoduje błąd? A także możliwe rozwiązanie?

góry dzięki

+0

W moim przypadku było to spowodowane błędną deklaracją 'XmlSerializer'. Sprawdź to także. – Mangesh

Odpowiedz

171

Albo ozdobić swój podmiot korzeniowy z atrybutem XmlRoot które zostaną wykorzystane w czasie kompilacji.

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

Lub określić atrybut root podczas de serializacji w środowisku wykonawczym.

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

XmlSerializer xs = new XmlSerializer(typeof(User),xRoot); 
+0

To działa i rozwiązuje problem, więc dziękuję. Czego nie rozumiem, dlaczego muszę to zrobić? Zawsze deserializuję cały czas i po raz pierwszy widzę ten błąd. – lloydsparkes

+5

Można dodać atrybut XmlRoot do klasy http://msdn.microsoft.com/en-us/library/83y7df3e(VS.71).aspx [XmlRoot (Namespace = "www.contoso.com", ElementName = "MyGroupName", DataType = "string", IsNullable = true)] –

+22

W języku XML jest rozróżniana wielkość liter. "Użytkownik" i "użytkownik" to różne nazwy. –

4

Jak mówi John Saunders, sprawdź, czy nazwy klas/właściwości pasują do obudowy kapitałowej Twojego XML. Jeśli tak nie jest, problem również wystąpi.

112

Nawet łatwiej jest po prostu dodać następujące adnotacje na szczycie swojej klasy:

[Serializable, XmlRoot("user")] 
public partial class User 
{ 
} 
+0

Proste i proste –

9

Komunikat o błędzie jest tak niejasne dla mnie miałem ten kod:

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

Zawiadomienie xmlSerializer jest tworzone za pomocą aResponse, ale w wyniku deserializacji odrzuciłem ją przypadkowo do bResonse.

+2

Po prostu miał podobny problem. xmlserializer został zainicjowany na typeof (T), a ja odrzuciłem na listę nurettin

+0

I zadeklarowałem 'XmlRoot (..)' na klasie potomnej 'ClassB' klasy nadrzędnej' ClassA'. Użyłem 'nowy XmlSerializer (typeof (ClassA)' zamiast na 'ClassB', a także rzucił na niego obiekt.Dzięki za wskazanie! –

16
XmlSerializer xs = new XmlSerializer(typeof(User), new XmlRootAttribute("yourRootName")); 
+2

To jest fantastyczne dla przypadków, w których w przeciwnym razie musiałbyś polegać na warunkowych atrybutach. –

+1

Bardzo proste i naprawiłem moją sprawę całkowicie Dziękuję! –

1

Mój problem był jednym z moich elementów miał atrybut xmlns:

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

Bez względu na to, co starałem atrybut xmlns wydawała się być złamanie serializatora, więc usunąłem żadnego śladu xmlns = "..." z pliku xml:

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

i voila! Wszystko działało.

Teraz analizuję plik xml, aby usunąć ten atrybut przed deserializacją. Nie wiem, dlaczego to działa, może mój przypadek jest inny, ponieważ element zawierający atrybut xmlns nie jest elementem głównym.

0

Jedyną rzeczą, która zadziałała w moim przypadku była użycie kodu Walentego Walentego. Korzystanie z Root Attr. w klasie Person nie pomogło.

Mam ten prosty XML:

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

C# klasa:

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

De-serializacji C# kod z główną metodą:

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; 
} 
3

najprostszym i najlepszym rozwiązaniem jest po prostu używać atrybutu XMLRoot w klasie, w którym Chcemy zdealizować.

odczuwalna:

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

używać również następujące DLL:

using System.Xml.Serialization; 
+1

Ktoś chce wyjaśnić? * Dlaczego * jest atrybutem "XmlRoot()' potrzebnym, aby rozwiązać ten problem? Istnieje 5 odpowiedzi, które mówią, "po prostu dodaj ten kod", a nie jedno wyjaśnienie Ludzie odpowiadają 7 lat później i wciąż jest to po prostu "Dodaj ten kod XmlRoot". Spośród wszystkich odpowiedzi wybrałem najnowszą, aby poprosić o wyjaśnienie: – Quantic

+0

Thankyou @Quantic, XmlRoot pozwala ci stworzyć nową wartość xml zamiast używając domyślnego katalogu głównego, możesz to spersonalizować, to tylko dekoracja, którą dodasz do swojego xml'a podczas kompilacji, wyeliminujesz kilka problemów ze zgodnością, mam nadzieję, że zrozumiesz mój punkt widzenia. –

0

Mój problem był taki, że element główny rzeczywiście ma xmlns = "abc123"

więc musiałem make XmlRoot ("elementname", NameSpace = "abc123")

0

Mój scenariusz polegał na tym, że pracowałem nad zadaniem, w którym kod był w VB.NET, a procedura, która deserializowała obiekty z łańcuchów xml, działała znakomicie dla dziesiątek zastosowań, ale wczoraj zakończyła się niepowodzeniem z "użytkownikiem xmlns =" ​​nie oczekiwano błędu (gdy został wyrzucony ciąg xml, który był serializacją obiektu, który miał właściwość, która była sama w sobie obiektem serializowanym). Odpowiedzi powyżej pomógł mi rozwiązać ten problem poprzez tę procedurę, która pracowała ...

' DESERIALIZE OBJECT FROM XML STRING 
Public Shared Function DeserializeFromXml(Of T)(ByVal xml As String) As T 
    Dim response As T = Nothing 
    Try 
    Using reader As TextReader = New StringReader(xml) 
     response = DirectCast(New XmlSerializer(GetType(T)).Deserialize(reader), T) 
    End Using 
    Catch ex As Exception 
    End Try 
    Return response 
End Function 

... skopiować ten kod i utworzyć nową procedurę, która pozwala rozmówca dostarczyć A „Korzeń nazwa atrybutu” ciąg. Nowa procedura deserializowała obiekt "problem" ze swojego serializowanego łańcucha xml bez żadnych błędów:

' DESERIALIZE OBJECT FROM XML STRING, SUPPLYING A ROOT ATTRIBUTE ELEMENT NAME 
Public Shared Function DeserializeFromXmlWithRootAttribute(Of T)(ByVal xml As String, ByVal rootAttributeName As String) As T 
    Dim response As T = Nothing 
    Try 
    Using reader As TextReader = New StringReader(xml) 
     Dim xra As New XmlRootAttribute() 
     xra.ElementName = rootAttributeName 
     xra.IsNullable = True 
     response = DirectCast(New XmlSerializer(GetType(T), xra).Deserialize(reader), T) 
    End Using 
    Catch ex As Exception 
    End Try 
    Return response 
End Function 
Powiązane problemy