Convertir cadena XML a objeto

Estoy recibiendo cadenas XML sobre un socket y me gustaría convertirlas a objetos C #.

Los mensajes son de la forma:

 1 stop  

Soy nuevo en .Net, y no estoy seguro de la mejor práctica para realizar esto. He usado JAXB para Java anteriormente, y no estaba seguro de si hay algo similar, o si esto se manejaría de una manera diferente.

Necesita usar la herramienta xsd.exe que se instala con el SDK de Windows en un directorio algo similar a:

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

Y en computadoras de 64 bits:

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

Y en las computadoras con Windows 10:

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

En la primera ejecución, usa xsd.exe y convierte su XML de muestra en un archivo XSD (archivo de esquema XML):

 xsd yourfile.xml 

Esto le proporciona yourfile.xsd , que en un segundo paso, puede convertir de nuevo utilizando xsd.exe en una clase C #:

 xsd yourfile.xsd /c 

Esto debería darle un archivo yourfile.cs que contendrá una clase C # que puede usar para deserializar el archivo XML que está obteniendo, como por ejemplo:

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

Debería funcionar bastante bien para la mayoría de los casos.

Actualización: el serializador XML tomará cualquier flujo como su entrada, ya sea un archivo o una secuencia de memoria estará bien:

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

o usa un StringReader:

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

Tienes dos posibilidades.

Método 1. Herramienta XSD


Supongamos que tiene su archivo XML en esta ubicación C:\path\to\xml\file.xml

  1. Abrir símbolo del sistema de desarrollador
    Puede encontrarlo en el Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools O si tiene Windows 8 puede simplemente comenzar a escribir el Símbolo del sistema de Desarrollador en la pantalla de Inicio
  2. Cambie la ubicación a su directorio de archivos XML escribiendo cd /D "C:\path\to\xml"
  3. Cree un archivo XSD desde su archivo xml escribiendo xsd file.xml
  4. Cree clases C # escribiendo xsd /c file.xsd

¡Y eso es! Ha generado clases C # desde el archivo xml en C:\path\to\xml\file.cs

Método 2 – Pegar especial


Se requiere Visual Studio 2012+ con .Net Framework> = 4.5 como objective del proyecto

  1. Copie el contenido de su archivo XML al portapapeles
  2. Agregue a su solución nuevo archivo de clase vacío ( Shift + Alt + C )
  3. Abra ese archivo y en el menú, haga clic en Edit > Paste special > Paste XML As Classes
    enter image description here

¡Y eso es!

Uso


El uso es muy simple con esta clase de ayuda:

 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(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(this string @this) where T : class { return JSON.Deserialize(@this.Trim()); } } } 

Todo lo que tienes que hacer ahora es:

  public class JSONRoot { public catalog catalog { get; set; } } // ... string xml = File.ReadAllText(@"D:\file.xml"); var catalog1 = xml.ParseXML(); string json = File.ReadAllText(@"D:\file.json"); var catalog2 = json.ParseJSON(); 

Pruebe este método para Convertir Xml a un objeto. Está hecho para exactamente lo que estás haciendo:

 protected T FromXml(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 ; } 

Llámalo usando este código:

 YourStrongTypedEntity entity = FromXml(YourMsgString); 

Simplemente ejecute su Visual Studio 2013 como administración … Copie el contenido de su archivo Xml. Vaya a Visual Studio 2013> Editar> Pegado especial> Pegue Xml como clases de C # Creará sus clases de c # según el contenido de su archivo Xml.

En caso de que alguien lo encuentre útil:

 public static class XmlConvert { public static string SerializeObject(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(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(); } } } 

Puedes llamarlo usando:

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

Puede usar xsd.exe para crear clases enlazadas al esquema en .Net y luego XmlSerializer para deserializar la cadena: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx

Puede generar clases como se describe arriba, o escribirlas manualmente:

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

Luego puede usar ExtendedXmlSerializer para serializar y deserializar.

Instalación Puede instalar ExtendedXmlSerializer desde nuget o ejecutar el siguiente comando:

 Install-Package ExtendedXmlSerializer 

Publicación por entregas:

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

Deserialización

 var obj2 = serializer.Deserialize(xml); 

Este soporte de serializador:

  • Deserialización xml del estándar XMLSerializer
  • Clase de serialización, struct, clase genérica, tipo primitivo, lista genérica y diccionario, matriz, enumeración
  • Clase de serialización con interfaz de propiedad
  • Referencia circular de referencia de serialización y referencia
  • Deserialización de la versión anterior de xml
  • Cifrado de propiedad
  • Serializador personalizado
  • Soporte XmlElementAttribute y XmlRootAttribute
  • POCO: todas las configuraciones (migraciones, serializador personalizado …) están fuera de la clase

ExtendedXmlSerializer admite .NET 4.5 o superior y .NET Core . Puede integrarlo con WebApi y AspCore.

Si tiene el xsd del mensaje xml, entonces puede generar clases c # usando la herramienta .Net xsd.exe.

Estas clases .Net pueden usarse para generar el xml.

Además de las otras respuestas aquí, puede usar naturalmente la clase XmlDocument , para lectura XML similar a DOM, o XmlReader , lector de avance rápido, para hacerlo “a mano”.

Simplificando la gran respuesta de Damian,

 public static T ParseXml(this string value) where T : class { var xmlSerializer = new XmlSerializer(typeof(T)); using (var textReader = new StringReader(value)) { return (T) xmlSerializer.Deserialize(textReader); } } 
 public string Serialize(T settings) { XmlSerializer serializer = new XmlSerializer(typeof(T)); StringWriter outStream = new StringWriter(); serializer.Serialize(outStream, settings); return outStream.ToString(); }