将 XML 从流反序列化到 List<T>

Fah*_*min 0 c# xml xml-deserialization xml-parsing

我在 XML 文件中有一些数据,正在通过流读取。我可以访问流对象,使用它我必须反序列化数据并填充列表。我的模型类如下所示

[XmlRoot("invoices")]
public class Invoice
{       
    [XmlElement(ElementName = "description", IsNullable= true)]
    public string Description { get; set; }

    [XmlElement(ElementName = "invoice_date")]
    public string InvoiceDate { get; set; }

    [XmlElement(ElementName = "invoice_number")]
    public string InvoiceNumber { get; set; }

    [XmlElement(ElementName = "date_due")]
    public string DateDue { get; set; }

    [XmlElement(ElementName = "amount")]
    public string Amount { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

下面是我用来读取数据的方法的片段

public List<Invoice> ParseRecords(Stream stream)
    {
        List<Invoice> invoices = new List<Invoice>();

        try
        {
            stream.Position = 0;
            XmlSerializer serializer = new XmlSerializer(typeof(List<Invoice>));
            invoices = (List<Invoice>)serializer.Deserialize(stream);
        }
        catch (Exception ex)
        {
            log.Error(ex);
        }

        return invoices;
    }
Run Code Online (Sandbox Code Playgroud)

XML 数据包含带有名为“invoices”的根标签的发票和带有标签“invoice”的多个子记录。没有为根元素定义命名空间,并且无法完成此操作,因为 XML 数据是从外部源接收的。XML 数据的格式正确。我面临的问题是,当执行 Deserialize() 方法时,它会抛出一个异常,指出 XML 文档中存在错误 (2, 2)。内部异常表示 {" 不是预期的。"}

谁能帮我弄清楚这里出了什么问题吗?

Mad*_*ddy 5

实现您期望的结果的一种方法如下

[XmlRoot(ElementName = "invoices")]
public class Invoices
{
    [XmlElement(ElementName = "invoice")]
    public List<Invoice> Invoice { get; set; }
}

    [XmlRoot("invoice")]
public class Invoice
{
    [XmlElement(ElementName = "description", IsNullable = true)]
    public string Description { get; set; }

    [XmlElement(ElementName = "invoice_date")]
    public string InvoiceDate { get; set; }

    [XmlElement(ElementName = "invoice_number")]
    public string InvoiceNumber { get; set; }

    [XmlElement(ElementName = "date_due")]
    public string DateDue { get; set; }

    [XmlElement(ElementName = "amount")]
    public string Amount { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

你的解析记录函数应该像下面这样

public Invoices ParseRecords(Stream stream)
{
    Invoices invoices;

    try
    {
        stream.Position = 0;
        XmlSerializer serializer = new XmlSerializer(typeof(Invoices);
        invoices = (Invoices)serializer.Deserialize(stream);
    }
    catch (Exception ex)
    {
        log.Error(ex);
    }

    return invoices;
}
Run Code Online (Sandbox Code Playgroud)