Десериализация XML из потока в список‹T›

У меня есть некоторые данные в файле 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; }
}

И ниже приведен фрагмент метода, который я использую для чтения данных.

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

XML-данные содержат счета-фактуры с корневым тегом «счета» и несколько дочерних записей с тегом «счет-фактура». Для корневого элемента не определено пространство имен, и это невозможно сделать, поскольку данные XML получены из внешнего источника. Данные XML имеют правильный формат. Проблема, с которой я сталкиваюсь, заключается в том, что когда метод Deserialize() выполняется, он выдает исключение, говорящее, что в XML-документе есть ошибка (2, 2). и внутреннее исключение говорит {"не ожидалось."}

Может ли кто-нибудь помочь мне понять, что здесь не так?


person Fahad Amin    schedule 21.05.2018    source источник
comment
Можете ли вы поделиться своим XML-контентом/данными, которые вы пытаетесь десериализовать?   -  person Maddy    schedule 21.05.2018
comment
‹invoices amount_type= import_type=› ‹invoice› ‹invoice_number›1234‹/invoice_number› ‹description›‹/description› ‹invoice_date›20150329‹/invoice_date› ‹date_due›20150412‹/date_due› ‹amount›0 /invoice› ‹invoice_number›2587‹/invoice_number› ‹description›‹/description› ‹invoice_date›20150529‹/invoice_date› ‹date_due›20150612‹/date_due› ‹amount›0‹/amount› ‹ /счета›   -  person Fahad Amin    schedule 21.05.2018


Ответы (2)


Один из способов достижения ожидаемого результата, как показано ниже.

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

И ваша функция разбора записей должна выглядеть примерно так:

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;
}
person Maddy    schedule 21.05.2018
comment
Большое спасибо, приятель! Вы спасатель жизни. Будьте здоровы :) - person Fahad Amin; 21.05.2018
comment
У меня есть еще один вопрос. Если в одном из тегов есть атрибут XML, десериализация всегда возвращает для него значение null. Например, если у суммы есть атрибут валюты, и я добавляю свойство Валюта строкового типа в свой класс модели, значение для этого свойства устанавливается равным нулю после десериализации. - person Fahad Amin; 22.05.2018
comment
Ваш класс Serializable изменится, если изменится ваш xml. - person Maddy; 22.05.2018
comment
Да, я добавил декоратор XmlAttribute к свойству, но он не десериализуется - person Fahad Amin; 22.05.2018
comment
Для меня ключом было сбросить позицию потока до нуля. - person Francisco Tena; 03.07.2019

в данных есть какой-то невидимый код (выглядит как пробел), возможно, это вызвано кодировкой.

person marya    schedule 21.05.2018