{“ <user xmlns =''>不是预期的。}反序列化Twitter XML


211

我正在通过OAuth从Twitter提取XML。

我正在向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 {“ <用户xmlns =”>不是预期的。“} System.Exception {System.InvalidOperationException}

现在,我进行了搜索,找到的最佳解决方案是在序列化内容时向序列化器添加空白名称空间,但是我没有序列化它,所以我不能。

我也有一些用于接收状态的代码,效果很好。

那么有人可以向我解释为什么会发生错误吗?以及可能的解决方案?

提前致谢。


就我而言,这是因为错误的声明XmlSerializer。所以也检查一下。
Mangesh

我必须将带有XmlAttribute的字段添加到类中。参见链接
Stefan Varga,

Answers:


261

可以使用XmlRoot属性装饰您的根实体,该属性将在编译时使用。

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

或在运行时取消序列化时指定root属性。

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

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

6
您可以将XmlRoot属性添加到类msdn.microsoft.com/zh-cn/library/83y7df3e(VS.71).aspx [XmlRoot(Namespace =“ www.contoso.com”,ElementName =“ MyGroupName”,DataType = “ string”,IsNullable = true)]
大卫·瓦伦丁2009年

39
XML区分大小写。“用户”和“用户”是不同的名称。
约翰·桑德斯

4
我之所以投票,是因为我觉得XmlRoot信息应该在类本身上定义,而不是在反序列化的位置上定义。在我看来,对于这种原因,Junto的解决方案更为出色。
GuiSim 2012年

4
@GuiSim您假设OP拥有对原始实体的控制权。这两个答案都是有效的。就我而言,我无法将XmlRoot添加到该实体,因为该实体用作MessageContract的一部分。使用上述方法适用于我的情况。
Bronumski 2013年

4
@GuiSim我不同意OP所说的。我可以完全控制我的根实体,但是不能使用root属性,因为它与MessageContract属性冲突。这两个答案都是有效的,并且替代方案已在注释中提出。关键是您否决了有效答案而不是错误答案。如果您不同意最好的话,那就不要投票。
Bronumski

135

甚至更容易的是将以下注释添加到类的顶部:

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

简单而直接
mayowa ogundele


12

错误消息非常模糊,对我来说,我有以下代码:

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

注意,xmlSerializer是使用aResponse实例化的,但是在反序列化时,我不小心将其强制转换为bResonse。


2
只是有一个类似的问题。xmlserializer初始化为typeof(T),而我正在转换为List <T>
nurettin 2012年

1
XmlRoot(..)在父母班ClassB的孩子班上宣布ClassA。我使用new XmlSerializer(typeof(ClassA)而不是on,ClassB并且也将对象转换为它。感谢您指出!
Shishir Gupta

6

最简单,最好的解决方案是只在您的类中使用XMLRoot属性,而您要在其中反序列化。

喜欢:

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

另外,使用以下Assembly

using System.Xml.Serialization;

3
有人要解释吗?为什么XmlRoot()属性需要解决这个问题?这里有5个答案,说“只需添加此代码”,而不是一个解释。人们在7年后回答,仍然只是“添加此XmlRoot代码”。在所有答案中,我选择了最新的答案以作解释。
量子

谢谢@ Quantic,XmlRoot允许您创建一个新的xml值,而不是使用默认的根目录来自定义该值。这只是一种装饰,您将在编译时将其添加到xml中。会消除一些兼容性问题。希望你明白我的意思。
Khawaja Asim

5

如John Saunders所说,请检查类/属性名称是否与XML的大写字母匹配。如果不是这种情况,也会出现此问题。


2

我的问题是我的元素之一具有xmlns属性:

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

无论我尝试了什么xmlns属性似乎都破坏了序列化程序,因此我从xml文件中删除了xmlns =“ ...”的任何痕迹:

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

和瞧!一切正常。

现在,我在反序列化之前解析xml文件以删除此属性。不知道为什么这样做,也许我的情况有所不同,因为包含xmlns属性的元素不是根元素。


您的文件指定RETS-RESPONSE位于“ blahblah”命名空间中。如果这与您的架构不匹配,则不会找到该元素。另外,添加默认名称空间也会引起其他各种参考问题。
Suncat2000

2

在我看来,唯一有效的方法是使用大卫·瓦伦丁代码。使用根属性。在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; }
}

从Main方法反序列化C#代码:

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

就我而言,我的xml具有多个名称空间和属性。所以我用这个网站来生成对象-https: //xmltocsharp.azurewebsites.net/

并使用下面的代码反序列化

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

该链接为将xml反序列化为类提供了巨大的帮助。
smr5

1

我的问题是根元素实际上有一个xmlns =“ abc123”

因此必须使XmlRoot(“ elementname”,NameSpace =“ abc123”)


1

上面的所有内容都不适合我,但这是:检查class的Root元素的名称与XML 区分大小写的名称完全一样。


1

除了这些错误,我没有任何工作

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

除了这种方式

1-您需要检查xml响应作为字符串(您试图反序列化为对象的响应)

2-使用在线工具进行字符串unescape和xml prettify / formatter

3- MAKE SURE该C#类(主类)你试图映射/反序列化XML字符串到HAS AN XmlRootAttribute该响应的根元素相匹配。

范例:

我的XML响应就像:

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

C#类定义和属性类似于:

[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 {
  .........
}

请注意,类定义没有“ XmlRootAttribute

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

当我尝试使用通用方法取消序列化时:

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

我收到上面的错误

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

现在,只需添加永久修复该问题的“ XmlRootAttribute”以及其他所有请求/响应,我都会遇到类似的问题:

[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
{
    ........
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.