239 votos

Cómo Deserializar documento XML

¿Cómo puedo Deserializar este documento 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>

Tengo este:

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

que no parecen funcionar :-(

289voto

Marc Gravell Puntos 482669

¿Y tú sólo tienes que guardar el xml a un archivo, y el uso xsd?

  1. Escribir el archivo en el disco (lo he denominado foo.xml)
  2. Generar el xsd: xsd foo.xml
  3. Generar el C#: xsd foo.xsd /classes

Et voila - y C# archivo de código que debe ser capaz de leer los datos a través de XmlSerializer:

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

(se incluyen los generados foo.cs en el proyecto)

182voto

Kevin Tighe Puntos 5573

He aquí una versión de trabajo. He cambiado el XmlElementAttribute etiquetas para XmlElement porque en el xml de la StockNumber, marca y Modelo de los valores son elementos, no atributos. También he quitado el reader.ReadToEnd(); ( function lee toda la secuencia y devuelve una cadena de caracteres, por lo que el Deserialze() la función no se puede utilizar el lector de...de la posición en la final de la secuencia). También tomé algunas libertades con el nombre :).

Aquí están las clases:

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

El Deserializar función:

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

Y un poco ajustado xml (tuve que agregar un nuevo elemento para envolver <Cars>...Net es exigente con la deserialización de matrices):

<?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>

117voto

Damian Drygiel Puntos 3230

Usted tiene dos posibilidades.

Método 1. XSD herramienta


Supongamos que usted tiene el archivo XML, en este lugar, C:\path\to\xml\file.xml

  1. Abierto Desarrollador Símbolo Del Sistema
    Usted puede encontrar en Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools O si usted tiene Windows 8 se puede comenzar a escribir Desarrollador de Símbolo del sistema en la pantalla de Inicio
  2. Cambiar la ubicación para el archivo XML directorio tecleando cd /D "C:\path\to\xml"
  3. Crear archivo XSD a partir de su archivo xml escribiendo xsd file.xml
  4. Crear clases de C# escribiendo xsd /c file.xsd

Y eso es todo! Se han generado clases de C# de archivo xml en C:\path\to\xml\file.cs

Método 2 - Pegado especial


Visual Studio 2012+

  1. Copia el contenido de tu archivo XML al portapapeles
  2. Agregar a la solución vacío nuevo archivo de clase (Shift+Alt+C)
  3. Abrir el archivo y en el menú haga clic en Edit > Paste special > Paste XML As Classes
    enter image description here

Y eso es todo!

Uso


Su uso es muy sencillo con esta clase auxiliar:

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

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

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

15voto

Joel Coehoorn Puntos 190579

A ver si esto ayuda:

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

Y, a falta de que el uso de la xsd.exe programa que viene con visual studio para crear un documento de esquema basado en que el archivo xml y, a continuación, volver a usar para crear una clase basada en el documento de esquema.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: