【问题标题】:Can't Deserialize XML无法反序列化 XML
【发布时间】:2013-07-26 19:24:55
【问题描述】:

我正在尝试反序列化以下 XML:

<?xml version="1.0" encoding="UTF-8"?>
<jobInfo
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<id>750x0000000005LAAQ</id>
<operation>insert</operation>
<object>Contact</object>
<createdById>005x0000000wPWdAAM</createdById>
<createdDate>2009-09-01T16:42:46.000Z</createdDate>
<systemModstamp>2009-09-01T16:42:46.000Z</systemModstamp>
<state>Open</state>
<concurrencyMode>Parallel</concurrencyMode>
<contentType>CSV</contentType>
<numberBatchesQueued>0</numberBatchesQueued>
<numberBatchesInProgress>0</numberBatchesInProgress>
<numberBatchesCompleted>0</numberBatchesCompleted>
<numberBatchesFailed>0</numberBatchesFailed>
<numberBatchesTotal>0</numberBatchesTotal>
<numberRecordsProcessed>0</numberRecordsProcessed>
<numberRetries>0</numberRetries>
<apiVersion>28.0</apiVersion>
</jobInfo>

我已经创建了这个对象:

public class JobInfo
{
    public string xmlns { get; set; }
    public string id { get; set; }
    public string operation { get; set; }
    public string @object { get; set; }
    public string createdById { get; set; }
    public string createdDate { get; set; }
    public string systemModstamp { get; set; }
    public string state { get; set; }
    public string concurrencyMode { get; set; }
    public string contentType { get; set; }
    public string numberBatchesQueued { get; set; }
    public string numberBatchesInProgress { get; set; }
    public string numberBatchesCompleted { get; set; }
    public string numberBatchesFailed { get; set; }
    public string numberBatchesTotal { get; set; }
    public string numberRecordsProcessed { get; set; }
    public string numberRetries { get; set; }
    public string apiVersion { get; set; }
}

public class RootObject
{
    public JobInfo jobInfo { get; set; }
}

而且,我正在使用此代码:

XmlSerializer serializer = new XmlSerializer(typeof(RootObject));
StringReader rdr = new StringReader(response);
RootObject resultingMessage = (RootObject)serializer.Deserialize(rdr);

但是,我收到此错误:

There is an error in XML document (1, 40).

{"<jobInfo xmlns='http://www.force.com/2009/06/asyncapi/dataload'> was not expected."}

我如何解释xmlns 属性?我的代码将它作为一个属性(因此,它失败了)......

【问题讨论】:

    标签: c# xml xml-deserialization


    【解决方案1】:

    目前您的代码期望 xmlns 作为元素,而不是属性。

    您应该将XmlSerialization attributes 添加到您的班级,如下所示:

    [XmlRoot("jobInfo", Namespace="http://www.force.com/2009/06/asyncapi/dataload"]
    public class JobInfo
    {
        [XmlAttribute]
        public string xmlns { get; set; }
        [XmlElement(ElementName = "id")]
        public string id { get; set; }
        ....
    }
    

    您可以在 MSDN 文章中找到更多信息:

    【讨论】:

    • 仅供参考,在我的测试中,除了 xmlns 属性仍未填充外,此方法有效。不确定这是限制还是属性配置错误。
    • 将命名空间名称移动到常量,并从那里填充它 - 这在 XML 架构更改之前不会改变。
    【解决方案2】:

    尝试使用XmlRootAttribute 指定Namespace

    [XmlRoot("jobInfo", Namespace = "http://www.force.com/2009/06/asyncapi/dataload")]
    public class JobInfo
    {
        [XmlElement("id")]
        public string Id { get; set; }
    
        [XmlElement("operation")]
        public string Operation { get; set; }
    
        [XmlElement("object")]
        public string Object { get; set; }
    
        [XmlElement("createdById")]
        public string CreatedById { get; set; }
    
        [XmlElement("createdDate")]
        public DateTime CreatedDate { get; set; }
    
        [XmlElement("systemModstamp")]
        public DateTime SystemModstamp { get; set; }
    
        [XmlElement("state")]
        public string State { get; set; }
    
        [XmlElement("concurrencyMode")]
        public string ConcurrencyMode { get; set; }
    
        [XmlElement("contentType")]
        public string ContentType { get; set; }
    
        [XmlElement("numberBatchesQueued")]
        public string NumberBatchesQueued { get; set; }
    
        [XmlElement("numberBatchesInProgress")]
        public string NumberBatchesInProgress { get; set; }
    
        [XmlElement("numberBatchesCompleted")]
        public string NumberBatchesCompleted { get; set; }
    
        [XmlElement("numberBatchesFailed")]
        public string NumberBatchesFailed { get; set; }
    
        [XmlElement("numberBatchesTotal")]
        public string NumberBatchesTotal { get; set; }
    
        [XmlElement("numberRecordsProcessed")]
        public string numberRecordsProcessed { get; set; }
    
        [XmlElement("numberRetries")]
        public string NumberRetries { get; set; }
    
        [XmlElement("apiVersion")]
        public string ApiVersion { get; set; }
    }
    

    代码:

    var xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
    <jobInfo xmlns=""http://www.force.com/2009/06/asyncapi/dataload"">
        <id>750x0000000005LAAQ</id>
        <operation>insert</operation>
        <object>Contact</object>
        <createdById>005x0000000wPWdAAM</createdById>
        <createdDate>2009-09-01T16:42:46.000Z</createdDate>
        <systemModstamp>2009-09-01T16:42:46.000Z</systemModstamp>
        <state>Open</state>
        <concurrencyMode>Parallel</concurrencyMode>
        <contentType>CSV</contentType>
        <numberBatchesQueued>0</numberBatchesQueued>
        <numberBatchesInProgress>0</numberBatchesInProgress>
        <numberBatchesCompleted>0</numberBatchesCompleted>
        <numberBatchesFailed>0</numberBatchesFailed>
        <numberBatchesTotal>0</numberBatchesTotal>
        <numberRecordsProcessed>0</numberRecordsProcessed>
        <numberRetries>0</numberRetries>
        <apiVersion>28.0</apiVersion>
    </jobInfo>";
    
    var serializer = new XmlSerializer(typeof(JobInfo));
    
    JobInfo jobInfo;
    
    using(var stream = new StringReader(xml))
    using(var reader = XmlReader.Create(stream))
    {
        jobInfo = (JobInfo)serializer.Deserialize(reader);
    }
    

    【讨论】:

    • 这不会填充xmlns 属性。
    • 正确,我删除了该属性,因为它应该是类的一部分。
    • @VMAtm xmlns 不是属性,它是默认命名空间
    • @rene OP 在他的班级中有这个属性。
    【解决方案3】:

    添加命名空间

      [XmlRoot("jobInfo",Namespace = "http://www.force.com/2009/06/asyncapi/dataload")]
      public class JobInfo
      {
         // get rid of the xmlns property
         // other properties stay
      }
    
    // there is no rootobject, JobInfo is your root
    XmlSerializer serializer = new XmlSerializer(typeof(JobInfo));
    StringReader rdr = new StringReader(response);
    JobInfo resultingMessage = (JobInfo)serializer.Deserialize(rdr);
    

    【讨论】:

    • 我现在得到的错误是Attribute 'XmlElement' is not valid on this declaration type
    • 你应该使用XmlRoot 属性作为类名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 2015-09-24
    • 2014-02-15
    相关资源
    最近更新 更多