【问题标题】:Deserialize Xml Using XmlReader and Class from xsd.exe使用 xsd.exe 中的 XmlReader 和 Class 反序列化 Xml
【发布时间】:2014-07-26 23:19:47
【问题描述】:

好的,在阅读一些教程时,我在尝试学习 XmlSerializer 时遇到了障碍。我已遵循所有推荐的步骤,但我的程序没有返回任何内容,或者返回 null。我创建了一个 XML 文件如下:

<?xml version='1.0' encoding='UTF-8' ?>
<WeeklyJobs>
   <DailyJobs Date = "02/03/2012"/>
  <DailyJobs Date = "02/04/2012" TotalJobs = "2">
    <Jobs>
      <Job JobName = "Job Name" Description = "Description"/>
      <Job JobName = "Job Name" Description = "Description"/>
    </Jobs>
  </DailyJobs>
  <DailyJobs Date = "02/05/2012" TotalJobs = "1">
    <Jobs>
      <Job JobName = "Job Name" Description = "Description"/>
    </Jobs>
  </DailyJobs>
  <DailyJobs Date = "02/06/2012" TotalJobs = "2">
    <Jobs>
      <Job JobName = "Job Name" Description = "Description"/>
      <Job JobName = "Job Name" Description = "Description"/>
    </Jobs>
  </DailyJobs>
  <DailyJobs Date = "02/07/2012"/>
  <DailyJobs Date = "02/08/2012" TotalJobs = "2">
    <Jobs>
      <Job JobName = "Job Name" Description = "Description"/>
      <Job JobName = "Job Name" Description = "Description"/>
    </Jobs>
  </DailyJobs>
</WeeklyJobs>

然后我使用 xsd.exe 生成 .xsd 文件,即:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="WeeklyJobs" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema"     xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="WeeklyJobs" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="DailyJobs">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Jobs" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Job" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:attribute name="JobName" type="xs:string" />
                        <xs:attribute name="Description" type="xs:string" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="Date" type="xs:string" />
            <xs:attribute name="TotalJobs" type="xs:string" />
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

创建架构后,我再次使用 xsd.exe 为我自动生成类:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class WeeklyJobs
{

    private WeeklyJobsDailyJobs[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("DailyJobs", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public WeeklyJobsDailyJobs[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class WeeklyJobsDailyJobs
{

    private WeeklyJobsDailyJobsJobsJob[][] jobsField;

    private string dateField;

    private string totalJobsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    [System.Xml.Serialization.XmlArrayItemAttribute("Job", typeof(WeeklyJobsDailyJobsJobsJob), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
    public WeeklyJobsDailyJobsJobsJob[][] Jobs
    {
        get
        {
            return this.jobsField;
        }
        set
        {
            this.jobsField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Date
    {
        get
        {
            return this.dateField;
        }
        set
        {
            this.dateField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string TotalJobs
    {
        get
        {
            return this.totalJobsField;
        }
        set
        {
            this.totalJobsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class WeeklyJobsDailyJobsJobsJob
{

    private string jobNameField;

    private string descriptionField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string JobName
    {
        get
        {
            return this.jobNameField;
        }
        set
        {
            this.jobNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Description
    {
        get
        {
            return this.descriptionField;
        }
        set
        {
            this.descriptionField = value;
        }
    }
}

在此之后,我将 .CS 文件添加到我的项目中,并创建了一个带有 TextBox 的简单 winform,以便在我反序列化一些 xml 后显示一些数据。就像我说的那样,程序启动了,TextBox 中没有显示任何内容,也没有抛出异常。这是我的winform:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

    }

    public string getExample()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(WeeklyJobs));
        WeeklyJobs jobs;
        string xml = @"<?xml version = ""1.0""?>"
            + @"<WeeklyJobs>"
            + @"<DailyJobs Date = ""02/03/2012""/>"
            + @"<DailyJobs Date = ""02/04/2012"" TotalJobs = ""2"">"
            + @"<Jobs>"
            + @"<Job JobName = ""Job Name"" Description = ""Description""/>"
            + @"<Job JobName = ""Job Name"" Description = ""Description""/>"
            + @"</Jobs>"
            + @"</DailyJobs>"
            + @"</WeeklyJobs>";

        // Create an XmlTextReader
        using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
        {
            jobs = (WeeklyJobs)serializer.Deserialize(reader);
        }

        return jobs.Items[0].Date;

    }

    private void Form1_Load(object sender, EventArgs e)
    {
        textBox1.Text = getExample();

    }


}

我有更多简单的 xml 示例可以工作,但第二次尝试向我的 xml 添加一些复杂性时我失败了。我必须弄清楚如何使用我在这里拥有的 xml。感谢您的帮助!谢谢大家!

【问题讨论】:

  • 根据我的经验,了解 xml 序列化如何工作的最佳方法是创建该类型的实例并对其进行序列化,以查看结果的样子。您可能会在测试中看到 xml 字符串中遗漏的一些重要内容。
  • 好吧,我只是想重现这个,似乎 XmlSerialization 代码有问题(错误 CS0030:无法将类型“DeleteMe.WeeklyJobsDailyJobsJobsJob[]”转换为“DeleteMe.WeeklyJobsDailyJobsJobsJob”/错误 CS0029:无法将类型“DeleteMe.WeeklyJobsDailyJobsJobsJob”隐式转换为“DeleteMe.WeeklyJobsDailyJobsJobsJob[]”)。我试图弄清楚。但我还要说,我通常的做法是手动编写我自己的类。如果我能找到问题,我会再发表评论。

标签: c# xml deserialization xmlreader


【解决方案1】:

好的,第一个问题是 XmlSerializer 构造函数引发了未处理的异常,但不知何故被吞没了。这就解释了为什么文本框是空的。我将调试器设置为在所有 CLR 异常上中断,并发现构造函数正在抛出 InvalidOperationException——显然是在代码生成过程中:

无法生成临时类(结果=1)。

错误 CS0030:无法将类型“DeleteMe.WeeklyJobsDailyJobsJobsJob[]”转换为“DeleteMe.WeeklyJobsDailyJobsJobsJob”

错误 CS0029:无法将类型“DeleteMe.WeeklyJobsDailyJobsJobsJob”隐式转换为“DeleteMe.WeeklyJobsDailyJobsJobsJob[]”

(构造函数也抛出了 FileNotFound 异常,但它也处理了它,所以你可以忽略它。)

似乎问题出在锯齿状数组上——您是否将一维数组更改为锯齿状数组?当然,错误消息将我指向了那个方向,但我也从未在 xsd 生成的代码中看到锯齿状数组,因此看起来很可疑。我将两次出现的WeeklyJobsDailyJobsJobsJob[][] 更改为WeeklyJobsDailyJobsJobsJob[],应用程序运行良好。

顺便说一句,您应该使用DateTime 作为您的日期,但XML 序列化程序不支持可变日期格式(请参阅https://stackoverflow.com/a/1118855/385844)。如果您无法控制源,则最好将字符串转换为日期,然后再将它们存储到数据库或任何地方。

【讨论】:

  • 你就是男人!我不得不同意你上面的评论。与其获取我收到的 xml Web 响应并使用 xsd.exe 工具创建我的架构和类,我应该退后一步问自己,这个类会是什么样子?然后进行更改,直到我的 xml 适合网络响应。非常感谢 phoog,您帮助我获得了一些宝贵的知识。
  • 现在,当我遍历我的反序列化对象时,我遇到了 NullReferenceExceptions。有点奇怪。我将不得不发布另一个question 来弄清楚。
猜你喜欢
  • 2011-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 2010-12-06
  • 1970-01-01
  • 2011-06-28
相关资源
最近更新 更多