从Web api反序列化XML数组

时间:2015-11-03 09:45:25

标签: c# xml xml-deserialization

首先,我按照here给出了答案,但我仍然无法完成以下工作。

我正在从Web API检索XML,返回的结果如下:

<ArrayOf__ptd_student_charges
    xmlns="http://schemas.datacontract.org/2004/07/something.something"
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <__ptd_student_charges>
        <accumulated_tuition>000.000</accumulated_tuition>
        <course_id>AAA-000/L</course_id>
        <invoice_date>01/01/2015</invoice_date>
        <lecturer_name>John Doe</lecturer_name>
        <net_tuition>000.000</net_tuition>
        <section_no>1</section_no>
        <semester>Summer</semester>
        <student_id>123456</student_id>
        <student_name>John Doe</student_name>
        <year>2015</year>
    </__ptd_student_charges>
    <__ptd_student_charges>
        <accumulated_tuition>000.000</accumulated_tuition>
        <course_id>AAA-000/L</course_id>
        <invoice_date>01/01/2015</invoice_date>
        <lecturer_name>John Doe</lecturer_name>
        <net_tuition>000.000</net_tuition>
        <section_no>1</section_no>
        <semester>Summer</semester>
        <student_id>123456</student_id>
        <student_name>John Doe</student_name>
        <year>2015</year>
    </__ptd_student_charges>  
</ArrayOf__ptd_student_charges>

我正在尝试将其反序列化为一系列学生。 我的学生班级定义如下:

public class Student
{
    [System.Xml.Serialization.XmlElement("accumulated_tuiton")]
    public double AccumulatedTution { get; set; }

    [System.Xml.Serialization.XmlElement("net_tuiton")]
    public double NetTuiton { get; set; }

    [System.Xml.Serialization.XmlElement("course_id")]
    public string CourseID { get; set; }

    [System.Xml.Serialization.XmlElement("invoice_date")]
    public DateTime InvoiceDate { get; set; }

    [System.Xml.Serialization.XmlElement("lecturer_name")]
    public string LecturerName { get; set; }

    [System.Xml.Serialization.XmlElement("semester")]
    public string Semester { get; set; }

    [System.Xml.Serialization.XmlElement("student_id")]
    public string StudentId { get; set; }

    [System.Xml.Serialization.XmlElement("student_name")]
    public string StudentName { get; set; }

    [System.Xml.Serialization.XmlElement("year")]
    public string Year { get; set; }

    [System.Xml.Serialization.XmlElement("section_no")]
    public int Section { get; set; }
}

我的学生集合定义如下:

[System.Xml.Serialization.XmlRoot("ArrayOf__ptd_student_charges xmlns=\"http://schemas.datacontract.org/2004/07/something.something\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance")]
public class StudentCollection
{
    [XmlArray("ArrayOf__ptd_student_charges")]
    [XmlArrayItem("__ptd_student_charges", typeof(Student))]
    public Student[] StudentArray { get; set; }
}

我正在使用此代码对结果进行反序列化:

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    StudentCollection collection;

    HttpWebRequest request = WebRequest.Create(stringUrl) as HttpWebRequest;
    HttpWebResponse response = request.GetResponse() as HttpWebResponse;

    XmlTextReader reader = new XmlTextReader(response.GetResponseStream());

    XmlSerializer serializer = new XmlSerializer(typeof(StudentCollection));
    collection = (StudentCollection)serializer.Deserialize(reader);

    reader.Close();
}

运行此操作后,我会收到一条带有消息的InvalidOperationException

  

ArrayOf__ptd_student_charges   的xmlns = 'http://schemas.datacontract.org/2004/07/something.something' &GT;   没想到。

我知道xmlns:...不应该在第一个标签中,但不幸的是它是,而且我不确定如何继续。

1 个答案:

答案 0 :(得分:1)

基本上,您需要在XML文件中支持默认的XML命名空间 - 您可以 通过在StudentCollection上指定它来执行此操作:

[System.Xml.Serialization.XmlRoot("ArrayOf__ptd_student_charges")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.datacontract.org/2004/07/something.something", IsNullable = false)]
public class StudentCollection
{
    [XmlArray("ArrayOf__ptd_student_charges")]
    [XmlArrayItem("__ptd_student_charges", typeof(Student))]
    public Student[] StudentArray { get; set; }
}

和实际的Student类:

[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.datacontract.org/2004/07/something.something", IsNullable = false)]
public class Student
{
   ..........
}

您可以在反序列化时以编程方式指定它:

XmlSerializer serializer = new XmlSerializer(typeof(StudentCollection),
                                             "http://schemas.datacontract.org/2004/07/something.something");

XmlSerializer的第二个参数是反序列化XML内容时要使用的默认 XML命名空间。

Extra tipp:如果你再次拥有一个XML文件,并且你需要获得代表该XML的C#代码类 - 如果你有Visual Studio 2012或更新版本,只需创建一个新代码class,将您的XML文件复制到剪贴板,然后使用Edit > Paste Special > Paste XML as classes,您将获得所有C#,包括所有XML属性和XML命名空间以及粘贴到Visual Studio中的所有内容