Преобразование XML-строки в объект

Я получаю XML-строки над сокетом и хотел бы преобразовать их в объекты С#.

Сообщения имеют форму:

<msg>
   <id>1</id>
   <action>stop</action>
</msg>

Я новичок в .Net, и я не уверен в лучшей практике для этого. Раньше я использовал JAXB для Java и не был уверен, есть ли что-то подобное, или если это будет обрабатываться по-другому.

Ответ 1

Вам нужно использовать инструмент xsd.exe, который устанавливается с SDK Windows в каталог, похожий на:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin

И на 64-битных компьютерах:

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin

И на компьютерах с Windows 10:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin

В первом запуске вы используете xsd.exe, и вы конвертируете образец XML в файл XSD (файл XML-схемы):

xsd yourfile.xml

Это дает вам yourfile.xsd, который на втором этапе можно снова преобразовать с помощью xsd.exe в класс С#:

xsd yourfile.xsd /c

Это должно дать вам файл yourfile.cs, который будет содержать класс С#, который вы можете использовать для десериализации XML файла, который вы получаете, например:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
msg resultingMessage = (msg)serializer.Deserialize(new XmlTextReader("yourfile.xml"));

В большинстве случаев это работает очень хорошо.

Обновление: XML-сериализатор примет любой поток в качестве своего ввода - либо файл, либо поток памяти будут в порядке:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
msg resultingMessage = (msg)serializer.Deserialize(memStream);

или используйте StringReader:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
StringReader rdr = new StringReader(inputString);
msg resultingMessage = (msg)serializer.Deserialize(rdr);

Ответ 2

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

Метод 1. Инструмент XSD


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

И это! Вы создали классы С# из XML файла в C:\path\to\xml\file.cs

Способ 2 - Вставить специальный


Требуемая Visual Studio 2012+ с .Net Framework >= 4.5 как цель проекта
  • Скопировать содержимое вашего XML файла в буфер обмена
  • Добавьте к вашему решению новый пустой файл класса (Shift + Alt + C)
  • Откройте этот файл и в меню нажмите Edit > Paste special > Paste XML As Classes
    enter image description here

И это!

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


Использование этого класса-помощника очень просто:

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>();

Ответ 3

Попробуйте этот метод для преобразования Xml в объект. Это сделано именно для того, что вы делаете:

protected T FromXml<T>(String xml)
{
    T returnedXmlClass = default(T);

    try
    {
        using (TextReader reader = new StringReader(xml))
        {
            try
            {
                returnedXmlClass = 
                    (T)new XmlSerializer(typeof(T)).Deserialize(reader);
            }
            catch (InvalidOperationException)
            {
                // String passed is not XML, simply return defaultXmlClass
            }
        }
    }
    catch (Exception ex)
    {
    }

    return returnedXmlClass ;        
}

Назовите его с помощью этого кода:

YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);

Ответ 4

Просто запустите Visual Studio 2013 в качестве администратора... Скопируйте содержимое вашего файла Xml. Перейти к Visual Studio 2013 > Edit > Paste Special > Вставить Xml как классы С# Он создаст ваши классы С# в соответствии с вашим содержимым файла Xml.

Ответ 5

На всякий случай кто-то может найти это полезным:

public static class XmlConvert
{
    public static string SerializeObject<T>(T dataObject)
    {
        if (dataObject == null)
        {
            return string.Empty;
        }
        try
        {
            using (StringWriter stringWriter = new System.IO.StringWriter())
            {
                var serializer = new XmlSerializer(typeof(T));
                serializer.Serialize(stringWriter, dataObject);
                return stringWriter.ToString();
            }
        }
        catch (Exception ex)
        {
            return string.Empty;
        }
    }

    public static T DeserializeObject<T>(string xml)
         where T : new()
    {
        if (string.IsNullOrEmpty(xml))
        {
            return new T();
        }
        try
        {
            using (var stringReader = new StringReader(xml))
            {
                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(stringReader);
            }
        }
        catch (Exception ex)
        {
            return new T();
        }
    }
}

Вы можете вызвать его, используя:

MyCustomObject myObject = new MyCustomObject();
string xmlString = XmlConvert.SerializeObject(myObject)
myObject = XmlConvert.DeserializeObject<MyCustomObject>(xmlString);

Ответ 6

Вы можете сгенерировать класс, как описано выше, или написать их вручную:

[XmlRoot("msg")]
public class Message
{
    [XmlElement("id")]
    public string Id { get; set; }
    [XmlElement("action")]
    public string Action { get; set; }
}

Затем вы можете использовать ExtendedXmlSerializer для сериализации и десериализации.

Instalation Вы можете установить ExtendedXmlSerializer из nuget или выполнить следующую команду:

Install-Package ExtendedXmlSerializer

Сериализация:

var serializer = new ConfigurationContainer().Create();
var obj = new Message();
var xml = serializer.Serialize(obj);

Десериализация

var obj2 = serializer.Deserialize<Message>(xml);

Эта поддержка сериализатора:

  • Deserialization xml из стандартного XMLSerializer
  • Класс сериализации, структура, общий класс, примитивный тип, общий список и словарь, массив, перечисление
  • Класс сериализации с интерфейсом свойств
  • Сериализация круговой ссылки и эталонного идентификатора
  • Дезабилизация старой версии xml
  • Шифрование свойств
  • Специальный сериализатор
  • Поддержка XmlElementAttribute и XmlRootAttribute
  • POCO - все конфигурации (миграции, пользовательский сериализатор...) находятся за пределами класса

ExtendedXmlSerializer поддерживает .NET 4.5 или выше и .NET Core. Вы можете интегрировать его с WebApi и AspCore.

Ответ 8

Если у вас есть xsd сообщения xml, вы можете сгенерировать классы С# с помощью инструмента .Net xsd.exe.

Затем эти .Net-классы можно использовать для генерации xml.

Ответ 9

В дополнение к другим ответам здесь вы можете естественно использовать класс XmlDocument для чтения в формате XML DOM или XmlReader, читатель с быстрой перемоткой вперед, чтобы сделать это "вручную".

Ответ 10

Упрощение ответа Дамиана,

public static T ParseXml<T>(this string value) where T : class
{
    var xmlSerializer = new XmlSerializer(typeof(T));
    using (var textReader = new StringReader(value))
    {
        return (T) xmlSerializer.Deserialize(textReader);
    }
}

Ответ 11

Еще один способ с расширенными инструментами генерации классов xsd to c #: xsd2code.com. Этот инструмент очень удобный и мощный. Он имеет гораздо больше настроек, чем инструмент xsd.exe из Visual Studio. Xsd2Code++ может быть настроен для использования списков или массивов и поддерживает большие схемы с большим количеством операторов импорта.

Обратите внимание на некоторые функции,

  • Генерирует бизнес-объекты из схемы XSD или файла XML для гибкого С# или код Visual Basic.
  • Поддержка Framework 2.0 до 4.x
  • Поддержка строго типизированной коллекции (List, ObservableCollection, MyCustomCollection).
  • Поддержка автоматических свойств.
  • Создание XML-методов чтения и записи (сериализация/десериализация).
  • Поддержка привязки данных (WPF, Xamarin).
  • WCF (атрибут DataMember).
  • Поддержка кодировки XML (UTF-8/32, ASCII, Unicode, Custom).
  • Чехол для верблюда /Pascal Case.
  • поддержка ограничений ([StringLengthAttribute = true/false], [RegularExpressionAttribute = true/false], [RangeAttribute = истина/ложь]).
  • Поддержка большого и сложного файла XSD.
  • Поддержка DotNet Core & стандарт

Ответ 12

Я знаю, что этот вопрос старый, но я наткнулся на него, и у меня есть другой ответ, чем, ну, все остальные :-)

Обычный способ (как упоминалось выше) - создать класс и десериализовать ваш xml.

Но (предупреждение: бесстыдная самореклама здесь) я только что опубликовал пакет Nuget, здесь, с которым вам не нужно. Вы просто идете:

string xml = System.IO.File.ReadAllText(@"C:\test\books.xml");
var book = Dandraka.XmlUtilities.XmlSlurper.ParseText(xml);

Это буквально, ничего больше не нужно. И, самое главное, если ваш xml изменяется, ваш объект также изменяется автоматически.

Если вы предпочитаете загружать dll напрямую, страница github находится здесь здесь.

Ответ 13

public string Serialize<T>(T settings)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    StringWriter outStream = new StringWriter();
    serializer.Serialize(outStream, settings);
    return outStream.ToString();
}