Как десериализовать XML-документ

Как десериализовать этот XML-документ:

<?xml version = "1.0" encoding = "utf-8"?>
<Cars>
  <Car>
    <StockNumber>1020</StockNumber>
    <Make>Nissan</Make>
    <Model>Sentra</Model>
  </Car>
  <Car>
    <StockNumber>1010</StockNumber>
    <Make>Toyota</Make>
    <Model>Corolla</Model>
  </Car>
  <Car>
    <StockNumber>1111</StockNumber>
    <Make>Honda</Make>
    <Model>Accord</Model>
  </Car>
</Cars>

У меня есть это:

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElementAttribute("StockNumber")]
    public string StockNumber{ get; set; }

    [System.Xml.Serialization.XmlElementAttribute("Make")]
    public string Make{ get; set; }

    [System.Xml.Serialization.XmlElementAttribute("Model")]
    public string Model{ get; set; }
}

.

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }

}

.

public class CarSerializer
{
    public Cars Deserialize()
    {
        Cars[] cars = null;
        string path = HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data/") + "cars.xml";

        XmlSerializer serializer = new XmlSerializer(typeof(Cars[]));

        StreamReader reader = new StreamReader(path);
        reader.ReadToEnd();
        cars = (Cars[])serializer.Deserialize(reader);
        reader.Close();

        return cars;
    }
}

которые, похоже, не работают :-(

Я думаю, вам нужно избегать угловых скобок в вашем образце документа.

harpo 13.12.2008 00:51

Этот ответ действительно хорош: stackoverflow.com/a/19613934/196210

Revious 19.02.2014 19:13

reader.ReadToEnd (); неправильно!!!

David Thielen 27.06.2020 01:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
499
3
707 881
17
Перейти к ответу Данный вопрос помечен как решенный

Ответы 17

Посмотрите, поможет ли это:

[Serializable()]
[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }
}

.

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElement()]
    public string StockNumber{ get; set; }

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

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

И в противном случае используйте программу xsd.exe, которая поставляется с Visual Studio, для создания документа схемы на основе этого XML-файла, а затем снова используйте его для создания класса на основе документа схемы.

Ответ принят как подходящий

Вот рабочая версия. Я изменил метки XmlElementAttribute на XmlElement, потому что в xml значения StockNumber, Make и Model являются элементами, а не атрибутами. Также я удалил reader.ReadToEnd(); (этот функция читает весь поток и возвращает строку, поэтому функция Deserialize() больше не может использовать считыватель ... позиция была в конце потока). Я также позволил себе несколько вольностей с наименованием :).

Вот классы:

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElement("StockNumber")]
    public string StockNumber { get; set; }

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

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


[Serializable()]
[System.Xml.Serialization.XmlRoot("CarCollection")]
public class CarCollection
{
    [XmlArray("Cars")]
    [XmlArrayItem("Car", typeof(Car))]
    public Car[] Car { get; set; }
}

Функция десериализации:

CarCollection cars = null;
string path = "cars.xml";

XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));

StreamReader reader = new StreamReader(path);
cars = (CarCollection)serializer.Deserialize(reader);
reader.Close();

И немного измененный xml (мне нужно было добавить новый элемент для обертывания <Cars> ... Net придирчив к десериализации массивов):

<?xml version = "1.0" encoding = "utf-8"?>
<CarCollection>
<Cars>
  <Car>
    <StockNumber>1020</StockNumber>
    <Make>Nissan</Make>
    <Model>Sentra</Model>
  </Car>
  <Car>
    <StockNumber>1010</StockNumber>
    <Make>Toyota</Make>
    <Model>Corolla</Model>
  </Car>
  <Car>
    <StockNumber>1111</StockNumber>
    <Make>Honda</Make>
    <Model>Accord</Model>
  </Car>
</Cars>
</CarCollection>

[Serializable] является избыточным при использовании XmlSerializer; XmlSerializer просто никогда не проверяет это. Точно так же большинство атрибутов [Xml...] избыточны, поскольку они просто имитируют поведение по умолчанию; т.е. по умолчанию свойство с именем StockNumber сохраняется как элемент с именем <StockNumber> - для этого нет необходимости в атрибутах.

Marc Gravell 08.05.2012 10:13

Обратите внимание, что XmlElementAttribute = XmlElement (это языковая функция, в которой вы можете опустить суффикс «Атрибут»). Реальным решением здесь является удаление вызова ReadToEnd () и добавление корневого узла. Но лучше использовать код от erymski, который решает вопрос (разобрать данный xml)

Flamefire 25.10.2014 03:06

Спасибо, Кевин, но что, если я удалю CarsCollection из образца XML. Я удалил Carscollection из классов и код Deserealize, но не преуспел.

Vikrant 27.07.2015 15:52

@Flamefire. +1 за удаление ReadToEnd, -1 за настройку XML, когда в этом нет необходимости.

Andrew Dennison 27.07.2020 17:37

Как насчет того, чтобы просто сохранить xml в файл и использовать xsd для создания классов C#?

  1. Запишите файл на диск (я назвал его foo.xml)
  2. Создайте xsd: xsd foo.xml
  3. Создайте C#: xsd foo.xsd /classes

Et voila - и файл кода C#, который должен иметь возможность читать данные через XmlSerializer:

    XmlSerializer ser = new XmlSerializer(typeof(Cars));
    Cars cars;
    using (XmlReader reader = XmlReader.Create(path))
    {
        cars = (Cars) ser.Deserialize(reader);
    }

(включить сгенерированный файл foo.cs в проект)

Ты мужчина! Спасибо. для всех, кому это нужно, «путь» может быть потоком, который вы создаете из веб-ответа, например: var resp = response.Content.ReadAsByteArrayAsync (); var stream = new MemoryStream (соответственно результат);

Induster 01.02.2013 21:36

Замечательная идея, но я не мог заставить ее работать правильно для моей немного более сложной модели с партиями вложенных массивов. Я продолжал получать ошибки преобразования типов для вложенных массивов - плюс сгенерированная схема именования оставляла желать лучшего. Поэтому я выбрал собственный маршрут.

GotDibbs 06.02.2013 20:21

Как добраться до xsd.exe

jwillmer 29.10.2013 16:00

xsd.exe доступен из командной строки Visual Studio, а не из командной строки Windows. Посмотрите, сможете ли вы открыть командную строку из Visual Studio в разделе Инструменты. Если нет, попробуйте получить к нему доступ из папки Visual Studio. Для VS 2012 он находился здесь: C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ Common7 \ Tools \ Shortcuts. В Windows 8 попробуйте поискать «Инструменты Visual Studio».

goku_da_master 16.10.2014 19:40

Для всех, кто ищет XSD. Вот тема SO: stackoverflow.com/questions/22975031/…

SOReader 13.10.2015 14:39

Если я не сохраняю xml в файл и не читаю его из ServiceModel.Channels.Message GetReaderAtBodyContents, который даст xmlReader, тогда как использовать xmlserializer?

user1532976 15.07.2020 00:28

Следующий фрагмент должен помочь (и вы можете игнорировать большинство атрибутов сериализации):

public class Car
{
  public string StockNumber { get; set; }
  public string Make { get; set; }
  public string Model { get; set; }
}

[XmlRootAttribute("Cars")]
public class CarCollection
{
  [XmlElement("Car")]
  public Car[] Cars { get; set; }
}

...

using (TextReader reader = new StreamReader(path))
{
  XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
  return (CarCollection) serializer.Deserialize(reader);
}

На самом деле это единственный ответ. У принятого ответа есть пара недостатков, которые могут сбить с толку новичков.

Flamefire 25.10.2014 03:03

@AndrewDennison, ты ни с кем не разговариваешь

John Deer 26.10.2020 18:56

Я не думаю, что .net «разборчив в десериализации массивов». Первый XML-документ сформирован неправильно. Корневого элемента нет, хотя вроде есть. Канонический XML-документ имеет корень и как минимум 1 элемент (если есть). В вашем примере:

<Root> <-- well, the root
  <Cars> <-- an element (not a root), it being an array
    <Car> <-- an element, it being an array item
    ...
    </Car>
  </Cars>
</Root>

попробуйте этот блок кода, если ваш XML-файл был сгенерирован где-то на диске и если вы использовали List<T>:

//deserialization

XmlSerializer xmlser = new XmlSerializer(typeof(List<Item>));
StreamReader srdr = new StreamReader(@"C:\serialize.xml");
List<Item> p = (List<Item>)xmlser.Deserialize(srdr);
srdr.Close();`

Примечание. C:\serialize.xml - это путь к моему XML-файлу. Вы можете изменить его под свои нужды.

У вас есть две возможности.

Способ 1. Инструмент XSD


Suppose that you have your XML file in this location C:\path\to\xml\file.xml
  1. Открыть Командная строка разработчика
    Вы можете найти его в Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools Или, если у вас Windows 8, можете просто начать вводить Командная строка разработчика в Стартовый экран
  2. Измените местоположение в каталоге файлов XML, набрав cd /D "C:\path\to\xml"
  3. Создайте XSD файл из вашего XML-файла, набрав xsd file.xml
  4. Создайте C# классы, набрав xsd /c file.xsd

Вот и все! Вы сгенерировали классы C# из XML-файла в C:\path\to\xml\file.cs

Метод 2 - Специальная вставка


Required Visual Studio 2012+
  1. Скопируйте содержимое вашего XML-файла в буфер обмена
  2. Добавьте в свое решение новый пустой файл класса (Shift + Alt + C)
  3. Откройте этот файл и в меню нажмите Edit > Paste special > Paste XML As Classes
    .

Вот и все!

использование


Этот вспомогательный класс очень прост в использовании:

using System;
using System.IO;
using System.Web.Script.Serialization; // Add reference: System.Web.Extensions
using System.Xml;
using System.Xml.Serialization;

namespace Helpers
{
    internal static class ParseHelpers
    {
        private static JavaScriptSerializer json;
        private static JavaScriptSerializer JSON { get { return json ?? (json = new JavaScriptSerializer()); } }

        public static Stream ToStream(this string @this)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(@this);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }


        public static T ParseXML<T>(this string @this) where T : class
        {
            var reader = XmlReader.Create(@this.Trim().ToStream(), new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
            return new XmlSerializer(typeof(T)).Deserialize(reader) as T;
        }

        public static T ParseJSON<T>(this string @this) where T : class
        {
            return JSON.Deserialize<T>(@this.Trim());
        }
    }
}

Все, что вам нужно сделать сейчас, это:

    public class JSONRoot
    {
        public catalog catalog { get; set; }
    }
    // ...

    string xml = File.ReadAllText(@"D:\file.xml");
    var catalog1 = xml.ParseXML<catalog>();

    string json = File.ReadAllText(@"D:\file.json");
    var catalog2 = json.ParseJSON<JSONRoot>();

+1 хороший ответ. Но команда Paste XML As Classes нацелена только на .NET 4.5.

ravy amiry 16.11.2013 14:24

Это отличный способ сгенерировать модель, если у вас установлен vs2012 +. После этого я выполнил очистку кода ReSharper, чтобы использовать автоматические свойства, а затем также сделал некоторые другие действия по наведению порядка. Вы можете сгенерировать с помощью этого метода, а затем при необходимости скопировать в более старый проект.

Scotty.NET 25.11.2014 12:10

Ориентация на .net4.5 не проблема. Просто запустите временный проект с помощью dotnet4.5, сделайте копию и вставьте туда и скопируйте исходный код в свой реальный проект.

LosManos 23.03.2015 12:46

где находится объект или класс «каталог»?

CB4 06.12.2016 17:44

'catalog' будет верхним (заголовочным) классом из файла, созданного в 'Специальной вставке'.

Jakubee 12.12.2016 20:29

Чтобы «Вставить XML как классы» отображалось в этом меню в сообществе VS 2017, вам необходимо установить «ASP.NET и веб-разработка». Если он отсутствует, просто запустите установщик VS еще раз, чтобы изменить вашу установку.

Slion 21.08.2018 20:31

Это не имеет ничего общего с вопросом, и ни у одного из наших клиентов нет установленной Visual Studio или ее инструментов.

Dan 09.10.2018 22:49

этот вспомогательный класс великолепен, но для тех, кто не использует VS в Windows, перейдите сюда, чтобы сначала превратить свой XML в классы: xmltocsharp.azurewebsites.net

kevinc 07.01.2019 02:53

Спасибо. Это мне очень помогло.

user890332 08.08.2019 22:41

@Damian, это хорошая прогулка по PasteSpecial. ИМО, вам не нужно загромождать свой ответ ненужными вспомогательными методами. OP не спрашивал о JSON. Кроме того, чтение всего текста в строку не требуется или идеально подходит для больших входных данных. Если у вас уже есть строка, используйте StringReader для преобразования.

Andrew Dennison 27.07.2020 18:13

Я продолжаю возвращаться к этому ответу ... и просто снова и снова использую специальную пасту

AbdulG 02.02.2021 21:21

Если вы получаете ошибки при использовании xsd.exe для создания файла xsd, используйте класс XmlSchemaInference, как упоминалось выше на msdn. Вот модульный тест, демонстрирующий:

using System.Xml;
using System.Xml.Schema;

[TestMethod]
public void GenerateXsdFromXmlTest()
{
    string folder = @"C:\mydir\mydata\xmlToCSharp";
    XmlReader reader = XmlReader.Create(folder + "\some_xml.xml");
    XmlSchemaSet schemaSet = new XmlSchemaSet();
    XmlSchemaInference schema = new XmlSchemaInference();

    schemaSet = schema.InferSchema(reader);


    foreach (XmlSchema s in schemaSet.Schemas())
    {
        XmlWriter xsdFile = new XmlTextWriter(folder + "\some_xsd.xsd", System.Text.Encoding.UTF8);
        s.Write(xsdFile);
        xsdFile.Close();
    }
}

// now from the visual studio command line type: xsd some_xsd.xsd /classes

Вы можете просто изменить один атрибут для свойства Cars car с XmlArrayItem на Xml Element. То есть из

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }
}

к

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlElement("Car")]
    public Car[] Car { get; set; }
}

Идея состоит в том, чтобы весь уровень обрабатывался для десериализации. Ознакомьтесь с образцом решения, которое решило мою аналогичную проблему.

<?xml version = "1.0" ?> 
 <TRANSACTION_RESPONSE>
    <TRANSACTION>
        <TRANSACTION_ID>25429</TRANSACTION_ID> 
        <MERCHANT_ACC_NO>02700701354375000964</MERCHANT_ACC_NO> 
        <TXN_STATUS>F</TXN_STATUS> 
        <TXN_SIGNATURE>a16af68d4c3e2280e44bd7c2c23f2af6cb1f0e5a28c266ea741608e72b1a5e4224da5b975909cc43c53b6c0f7f1bbf0820269caa3e350dd1812484edc499b279</TXN_SIGNATURE> 
        <TXN_SIGNATURE2>B1684258EA112C8B5BA51F73CDA9864D1BB98E04F5A78B67A3E539BEF96CCF4D16CFF6B9E04818B50E855E0783BB075309D112CA596BDC49F9738C4BF3AA1FB4</TXN_SIGNATURE2> 
        <TRAN_DATE>29-09-2015 07:36:59</TRAN_DATE> 
        <MERCHANT_TRANID>150929093703RUDZMX4</MERCHANT_TRANID> 
        <RESPONSE_CODE>9967</RESPONSE_CODE> 
        <RESPONSE_DESC>Bank rejected transaction!</RESPONSE_DESC> 
        <CUSTOMER_ID>RUDZMX</CUSTOMER_ID> 
        <AUTH_ID /> 
        <AUTH_DATE /> 
        <CAPTURE_DATE /> 
        <SALES_DATE /> 
        <VOID_REV_DATE /> 
        <REFUND_DATE /> 
        <REFUND_AMOUNT>0.00</REFUND_AMOUNT> 
    </TRANSACTION>
  </TRANSACTION_RESPONSE> 

Вышеупомянутый XML обрабатывается на двух уровнях

  [XmlType("TRANSACTION_RESPONSE")]
public class TransactionResponse
{
    [XmlElement("TRANSACTION")]
    public BankQueryResponse Response { get; set; }

}

Внутренний уровень

public class BankQueryResponse
{
    [XmlElement("TRANSACTION_ID")]
    public string TransactionId { get; set; }

    [XmlElement("MERCHANT_ACC_NO")]
    public string MerchantAccNo { get; set; }

    [XmlElement("TXN_SIGNATURE")]
    public string TxnSignature { get; set; }

    [XmlElement("TRAN_DATE")]
    public DateTime TranDate { get; set; }

    [XmlElement("TXN_STATUS")]
    public string TxnStatus { get; set; }


    [XmlElement("REFUND_DATE")]
    public DateTime RefundDate { get; set; }

    [XmlElement("RESPONSE_CODE")]
    public string ResponseCode { get; set; }


    [XmlElement("RESPONSE_DESC")]
    public string ResponseDesc { get; set; }

    [XmlAttribute("MERCHANT_TRANID")]
    public string MerchantTranId { get; set; }

}

Точно так же вам нужно несколько уровней с car as arrayПроверьте этот пример для многоуровневой десериализации

Попробуйте этот универсальный класс для сериализации и десериализации XML.

public class SerializeConfig<T> where T : class
{
    public static void Serialize(string path, T type)
    {
        var serializer = new XmlSerializer(type.GetType());
        using (var writer = new FileStream(path, FileMode.Create))
        {
            serializer.Serialize(writer, type);
        }
    }

    public static T DeSerialize(string path)
    {
        T type;
        var serializer = new XmlSerializer(typeof(T));
        using (var reader = XmlReader.Create(path))
        {
            type = serializer.Deserialize(reader) as T;
        }
        return type;
    }
}

Мое решение:

  1. Используйте Edit > Past Special > Paste XML As Classes, чтобы получить класс в вашем коде
  2. Попробуйте что-то вроде этого: создайте список этого класса (List<class1>), затем используйте XmlSerializer для сериализации этого списка в файл xml.
  3. Теперь вы просто замените тело этого файла своими данными и попытайтесь его записать на deserialize.

Код:

StreamReader sr = new StreamReader(@"C:\Users\duongngh\Desktop\Newfolder\abc.txt");
XmlSerializer xml = new XmlSerializer(typeof(Class1[]));
var a = xml.Deserialize(sr);
sr.Close();

ПРИМЕЧАНИЕ: вы должны обратить внимание на корневое имя, не меняйте его. Мой - "ArrayOfClass1"

Как насчет универсального класса для десериализации XML-документа

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Generic class to load any xml into a class
// used like this ...
// YourClassTypeHere InfoList = LoadXMLFileIntoClass<YourClassTypeHere>(xmlFile);

using System.IO;
using System.Xml.Serialization;

public static T LoadXMLFileIntoClass<T>(string xmlFile)
{
    T returnThis;
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    if (!FileAndIO.FileExists(xmlFile))
    {
        Console.WriteLine("FileDoesNotExistError {0}", xmlFile);
    }
    returnThis = (T)serializer.Deserialize(new StreamReader(xmlFile));
    return (T)returnThis;
}

Эта часть может быть, а может и не понадобиться. Откройте XML-документ в Visual Studio, щелкните правой кнопкой мыши XML, выберите свойства. Затем выберите файл схемы.

Это позволило мне немного сжать код бизнес-логики и централизовать функциональность во вспомогательном классе со всеми созданными мной классами <T>. У меня уже был XML в строке, поэтому я могу сжать его до следующего: `public static T LoadXMLFileIntoClass <T> (string xmlData)` {`XmlSerializer serializer = new XmlSerializer (typeof (T)); `return (T) serializer.Deserialize (новый StringReader (xmlData)); `} Спасибо!

pwrgreg007 04.02.2020 21:30

Ансер Кевина хорош, кроме того факта, что в реальном мире вы часто не можете изменить исходный XML в соответствии со своими потребностями.

Для исходного XML тоже есть простое решение:

[XmlRoot("Cars")]
public class XmlData
{
    [XmlElement("Car")]
    public List<Car> Cars{ get; set; }
}

public class Car
{
    public string StockNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

И тогда вы можете просто вызвать:

var ser = new XmlSerializer(typeof(XmlData));
XmlData data = (XmlData)ser.Deserialize(XmlReader.Create(PathToCarsXml));

Спасибо! Ваш ответ - именно то, что мне нужно, так как я не хотел изменять файлы журнала размером в гигабайты.

Colin 12.03.2018 12:19

Хотя стоит упомянуть, что решение XmlSerializer очень элегантно, но, по общему признанию, также не очень быстро и чутко реагирует на неожиданные данные Xml. Поэтому, если ваша проблема не требует полной десериализации, вам следует подумать об использовании только более прагматичного и производительного класса XmlReader и перебрать элементы <Car>.

Kim Homann 21.03.2018 14:03

Для начинающих

Я нашел ответы здесь очень полезными, в которых говорится, что я все еще борюсь (немного), чтобы заставить это работать. Итак, если это кому-то поможет, я расскажу о рабочем решении:

XML из исходного вопроса. XML находится в файле Class1.xml, path к этому файлу используется в коде для определения местоположения этого XML-файла.

Я использовал ответ @erymski, чтобы это заработало, поэтому создал файл с именем Car.cs и добавил следующее:

using System.Xml.Serialization;  // Added

public class Car
{
    public string StockNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

[XmlRootAttribute("Cars")]
public class CarCollection
{
    [XmlElement("Car")]
    public Car[] Cars { get; set; }
}

Другой фрагмент кода предоставлен @erymski ...

using (TextReader reader = new StreamReader(path))
{
  XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
  return (CarCollection) serializer.Deserialize(reader);
}

... входит в вашу основную программу (Program.cs) в static CarCollection XCar() следующим образом:

using System;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApp2
{
    class Program
    {

        public static void Main()
        {
            var c = new CarCollection();

            c = XCar();

            foreach (var k in c.Cars)
            {
                Console.WriteLine(k.Make + " " + k.Model + " " + k.StockNumber);
            }
            c = null;
            Console.ReadLine();

        }
        static CarCollection XCar()
        {
            using (TextReader reader = new StreamReader(@"C:\Users\SlowLearner\source\repos\ConsoleApp2\ConsoleApp2\Class1.xml"))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
                return (CarCollection)serializer.Deserialize(reader);
            }
        }
    }
}

Надеюсь, поможет :-)

У меня это сработало. Это отлично работающее решение для данного ввода xml (как в примере OP). [XmlElement ("Car")] - правильный атрибут. В других примерах они использовали XmlArray и т. д., Которые не нужны, если у нас есть свойство, определенное как public Car [] Cars {get; набор; } и он десериализует его правильно. Спасибо.

Diwakar Padmaraja 28.01.2019 19:24
async public static Task<JObject> XMLtoNETAsync(XmlDocument ToConvert)
{
    //Van XML naar JSON
    string jsonText = await Task.Run(() => JsonConvert.SerializeXmlNode(ToConvert));

    //Van JSON naar .net object
    var o = await Task.Run(() => JObject.Parse(jsonText));

    return o;
}

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

gehbiszumeis 24.05.2019 12:02

Один лайнер:

var object = (Cars)new XmlSerializer(typeof(Cars)).Deserialize(new StringReader(xmlString));

Другие вопросы по теме