{"<user xmlns = ''> beklenmiyordu.} Twitter XML'in serisini kaldırma


211

OAuth aracılığıyla Twitter'dan XML çekiyorum.

Aşağıdaki XML döndüren http://twitter.com/account/verify_credentials.xml adresine bir istekte bulunuyorum :

<?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>

Deserialize için aşağıdaki kodu kullanıyorum:

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

Ve Usersınıfım için aşağıdakiler var :

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

}

Ancak yukarıdaki XML'in serileştirmesini kaldırdığında, uygulama aşağıdakileri atar:

  • $ exception {"XML belgesinde (2, 2) bir hata var."} System.Exception {System.InvalidOperationException}

  • InnerException {"<user xmlns = ''> beklenmiyordu."} System.Exception {System.InvalidOperationException}

Şimdi araştırdım ve bulabildiğim en iyi çözüm, içeriği serileştirdiğinizde serileştiriciye boş ad alanları eklemektir, ancak bunu serileştirmiyorum, bu yüzden yapamam.

Ayrıca iyi çalışır Durumları almak için bazı kod var.

Birisi bana hatanın neden olduğunu açıklayabilir mi? Olası bir çözümün yanı sıra?

Şimdiden teşekkürler.


Benim durumumda, bunun yanlış beyanı yüzünden oldu XmlSerializer. Bu yüzden de kontrol edin.
17'de Mangesh

Sınıfa XmlAttribute ile alan eklemek zorunda kaldı . Bkz. Bağlantı
Stefan Varga

Yanıtlar:


263

Kök varlığınızı derleme zamanında kullanılacak XmlRoot özniteliğiyle süsleyin.

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

Veya çalışma zamanında serileştirme yaparken kök niteliğini belirtin.

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

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

6
Sen sınıf bir XmlRoot niteliğini ekleyebilirsiniz msdn.microsoft.com/en-us/library/83y7df3e(VS.71).aspx [XmlRoot (Namespace = "www.contoso.com", ElementName = "MyGroupName", VeriTürü = "string", IsNullable = true)]
david valentine

39
XML büyük / küçük harfe duyarlıdır. "Kullanıcı" ve "kullanıcı" farklı adlardır.
John Saunders

4
Ben reddedildi çünkü XmlRoot bilgilerinin serileştirildiği yerde değil, sınıfın kendisinde tanımlanması gerektiğini hissediyorum. Bu neden için Junto'nun çözümü bence üstün.
GuiSim

4
@GuiSim OP'nin orijinal varlık üzerinde kontrol sahibi olduğunu varsayıyorsunuz. Her iki cevap da geçerlidir. Benim durumumda bir MessageContract parçası olarak kullanıldığı gibi varlık XmlRoot ekleyemezsiniz. Yukarıdaki yöntemi kullanmak benim senaryom için çalışır.
Bronumski

4
@GuiSim OP'nin söylediklerine katılmıyorum. Kök varlığım üzerinde tam denetime sahibim, ancak MessageContract özniteliğiyle çakıştığı için rootattribute'ı kullanamıyorum. Her iki cevap da geçerlidir ve alternatif yorumlarda sunulmuştur. Mesele şu ki, yanlış bir cevap değil, geçerli bir cevabı oyluyorsunuz. En iyisi olduğunu kabul etmiyorsanız, sadece oy vermeyin.
Bronumski

135

Daha da kolayı, sadece sınıfınızın en üstüne şu ek açıklamaları eklemektir:

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

Simple and Straightforward
mayowa ogundele

25
XmlSerializer xs = new XmlSerializer(typeof(User), new XmlRootAttribute("yourRootName")); 

2
Bu, aksi takdirde nitelikler için koşullara güvenmeniz gereken durumlar için harika.
Den Delimarsky

2
Çok basit ve davam tamamen düzeltildi. Teşekkürler!
AW

12

Hata mesajı çok belirsiz, benim için bu kodu vardı:

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

Dikkat xmlSerializer aResponse ile başlatıldı, ancak serileştirme üzerine yanlışlıkla bResonse'a döktüm.


2
Sadece benzer bir sorun vardı. xmlserializer typeof (T) olarak başlatıldı ve List <T> 'a yayın yapıyordum
nurettin

1
Ebeveyn sınıfının XmlRoot(..)alt sınıfında beyan ettim . Açık yerine kullandım ve ona nesne döktüm. İşaret ettiğiniz için teşekkürler! ClassBClassAnew XmlSerializer(typeof(ClassA)ClassB
Shishir Gupta

6

En basit ve en iyi çözüm, serisini kaldırmak istediğiniz sınıfınızda XMLRoot niteliğini kullanmaktır .

Sevmek:

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

Ayrıca, aşağıdaki Montajı kullanın :

using System.Xml.Serialization;

3
Bir açıklama yapmak isteyen var mı? Bu sorunu gidermek için öznitelik nedenXmlRoot() gereklidir? Burada bir açıklama değil, "sadece bu kodu ekle" diyen 5 cevap var. İnsanlar 7 yıl sonra cevap veriyor ve hala "Bu XmlRoot kodunu ekle". Tüm cevaplardan açıklama istemek için en yenisini seçtim.
Quantic

Teşekkürler @Quantic, XmlRoot, özelleştirebileceğiniz varsayılan kök kullanmak yerine yeni bir xml değeri oluşturmanıza izin verir. Sadece derleme zamanında xml'nize ekleyeceğiniz dekorasyon. Bazı durumlarda uyumluluk sorunlarını ortadan kaldıracaktır. Umarım anladım.
Khawaja Asim

5

John Saunders'ın dediği gibi, sınıf / özellik adlarının XML'nizin büyük harfleriyle eşleşip eşleşmediğini kontrol edin. Durum böyle değilse, sorun da ortaya çıkacaktır.


2

Benim sorunum öğelerimden biri xmlns özniteliğine sahipti:

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

Ne xmlns özniteliğini denediğim önemli değil serileştiriciyi kırıyor gibiydi, bu yüzden xml dosyasından xmlns = "..." herhangi bir izini kaldırdım:

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

ve işte! Her şey işe yaradı.

Şimdi serisini kaldırmadan önce bu özniteliği kaldırmak için xml dosyasını ayrıştırıyorum. Neden çalıştığından emin değilim, belki benim durumum farklı çünkü xmlns özniteliğini içeren öğe kök öğe değil.


Dosyanız RETS-RESPONSE öğesinin "blahblah" ad alanında olduğunu belirtti. Bu şemanızla eşleşmezse, öğe bulunamadı. Ayrıca, varsayılan bir ad alanı eklemek, her türlü diğer başvuru sorunlarına da neden olur.
Suncat2000

2

Benim durumumda işe yarayan tek şey david valentine kodunu kullanmaktı. Kök Attr. Kişi sınıfında yardımcı olmadı.

Bu basit Xml var:

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

C # sınıfı:

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

Bir Ana yöntemden Seri Kaldırma C # kodu:

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

Benim durumumda, xml'imin birden çok ad alanı ve özelliği vardı. Bu yüzden nesneleri oluşturmak için bu siteyi kullandım - https://xmltocsharp.azurewebsites.net/

Ve seriyi kaldırmak için aşağıdaki kodu kullandı

 XmlDocument doc =  new XmlDocument();
        doc.Load("PathTo.xml");
        User obj;
        using (TextReader textReader = new StringReader(doc.OuterXml))
        {
            using (XmlTextReader reader = new XmlTextReader(textReader))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(User));
                obj = (User)serializer.Deserialize(reader);
            }
        }

Bağlantı, xml'yi sınıfa ayırmak için büyük bir yardım sağladı.
smr5

1

Benim sorunum kök öğenin aslında bir xmlns = "abc123" olmasıdır

Bu yüzden XmlRoot ("elementname", NameSpace = "abc123") yapmak zorundaydı


1

Yukarıdaki tüm benim için çalıştı, ama şuydu: sınıfın Kök öğesinin adıdır kontrol ediniz tam XML den biri gibi hassas durumda .


1

Hiçbir şey çalıştı bu hataları benim için HARİÇ

... was not expected, 
... there is an error in XML document (1,2)
... System.FormatException Input String was not in correct format ...

Bu yol dışında

1- xml yanıtını dize olarak incelemeniz gerekir (bir nesnenin serisini serileştirmeye çalıştığınız yanıt)

2- Dize unescape ve xml prettify / formatter için çevrimiçi araçlar kullanın

3- EMİN OLUN eşlemek çalışıyoruz C # sınıf (ana sınıfı) / xml dizesi serisini olduğunu BİR XmlRootAttribute HAS yanıtın kök öğesi eşleşir.

xmaple:

XML Yanıtım şöyle görünüyordu:

<ShipmentCreationResponse xmlns="http://ws.aramex.net/ShippingAPI/v1/">
       <Transaction i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>
           ....

Ve C # sınıfı tanım + öznitelikleri şöyleydi:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="ShipmentCreationResponse", WrapperNamespace="http://ws.aramex.net/ShippingAPI/v1/", IsWrapped=true)]
public partial class ShipmentCreationResponse {
  .........
}

Sınıf tanımının " XmlRootAttribute " olmadığını unutmayın

[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.aramex.net/ShippingAPI/v1/", IsNullable = false)]

Ve ben genel bir yöntem kullanarak seri hale getirmeye çalıştığınızda:

public static T Deserialize<T>(string input) where T : class
{
    System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(T));

    using (System.IO.StringReader sr = new System.IO.StringReader(input))
    {
        return (T)ser.Deserialize(sr);
    }
}





var _Response = GeneralHelper.XMLSerializer.Deserialize<ASRv2.ShipmentCreationResponse>(xml);

Yukarıdaki hataları alıyordum

... was not expected, ... there is an error in XML document (1,2) ...

Şimdi sadece "her zaman ve diğer tüm istek / yanıtlar için sorunu düzeltti" XmlRootAttribute "ekleyerek ben ile benzer bir sorun vardı:

[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.aramex.net/ShippingAPI/v1/", IsNullable = false)]

..

[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ws.aramex.net/ShippingAPI/v1/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.aramex.net/ShippingAPI/v1/", IsNullable = false)]
public partial class ShipmentCreationResponse
{
    ........
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.