2012-06-28 15 views
5

Comencé a practicar con XML y C# y tengo un mensaje de error de "Hay un error en el documento XML (3,2)". Después de mirar el archivo, no veo nada malo en él (fíjate, probablemente me haya perdido algo porque soy un novato). Estoy usando una aplicación de consola para C# en este momento. Intento devolver una lista de Aventureros y solo una nota al margen, el elemento GEAR es opcional. Aquí es lo que tengo hasta ahora:Deserializar XML al objeto (necesita devolver una lista de objetos)

archivo XML - Prueba1

<?xml version="1.0" encoding="utf-8"?> 
<Catalog> 
    <Adventurer> 
     <ID>001</ID> 
     <Name>John Smith</Name> 
     <Address>123 Fake Street</Address> 
     <Phone>123-456-7890</Phone> 
     <Gear> 
      <Attack> 
       <Item> 
        <IName>Sword</IName> 
        <IPrice>15.00</IPrice> 
       </Item> 
       <Item> 
        <IName>Wand</IName> 
        <IPrice>20.00</IPrice> 
       </Item>   
      </Attack> 
      <Defense> 
       <Item> 
        <IName>Shield</IName> 
        <IPrice>5.00</IPrice> 
       </Item> 
     </Defense> 
     </Gear> 
    </Adventurer> 
    <Adventurer> 
     <ID>002</ID> 
     <Name>Guy noone likes</Name> 
     <Address>Some Big House</Address> 
     <Phone>666-666-6666</Phone> 
     <Gear></Gear> 
    </Adventurer> 
</Catalog> 

C# Clases

public class Catalog 
{ 
    List<Adventurer> Adventurers { get; set; } 
} 

public class Adventurer 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Address { get; set; } 
    public string Phone { get; set; } 
    public Gear Gear { get; set; } 
} 

public class Gear 
{ 
    public List<Item> Attack { get; set; } 
    public List<Item> Defense { get; set; } 
} 

public class Item 
{ 
    public string IName { get; set; } 
    public decimal IPrice { get; set; } 
} 

Serialize Función - Cuando el problema se produce en la línea 5

Catalog obj = null; 
string path = @"C:\Users\Blah\Desktop\test1.xml"; 
XmlSerializer serializer = new XmlSerializer(typeof(Catalog)); 
StreamReader reader = new StreamReader(path); 
obj = (Catalog)serializer.Deserialize(reader); 
reader.Close(); 

Console.ReadLine(); 
+0

Consulte "[¿Las preguntas específicas de un idioma deben contener el nombre del idioma en el título?] (Http://meta.stackexchange.com/questions/19190/should-language-specific-questions-contain-the-language) -name-in-the-title) ", donde el consenso es" no, no deberían ". –

Respuesta

3

La cuestión es la lista de los aventureros en el catálogo:

<?xml version="1.0" encoding="utf-8"?> 
<Catalog> 
    <Adventurers> <!-- you're missing this --> 
     <Adventurer> 
     </Adventurer> 
     ... 
     <Adventurer> 
     </Adventurer> 
    </Adventurers> <!-- and missing this --> 
</Catalog> 

Usted no tiene el elemento de envoltura para la recogida Adventurers.

EDITAR: Por cierto, creo que la forma más fácil de construir la estructura XML y asegurarse de que sea compatible es crear los objetos en C#, luego ejecutar el XmlSerializer incorporado y usar su salida XML como una base para cualquier XML que creo en lugar de formarlo a mano.

+0

Gracias por el consejo. Pude hacer que funcionara. Así que supongo que tendría que crear un "aventurero" en C# y luego serializarlo en XML ¿verdad? –

+0

@ J-Y: Crearía un 'Catálogo' típico con datos de muestra en código C#, luego lo serializaría en XML para usarlo como una plantilla para cuando haga su propio contenido XML. –

1

Su XML no acaba de alinearse con sus objetos ... es decir, estos dos ...

public string City { get; set; } 

y

<Address>123 Fake Street</Address> 

Cambio ciudad en la dirección o viceversa, y que debería solucionar el problema .

Editar: Tienes que esto funcione en un proyecto de prueba, la combinación de todas nuestras respuestas ...

Añadir <Adventurers> etiqueta después de <Catalog> (y </Adventurers> antes </Catalog>) y cambiar

List<Adventurer> Adventurers { get; set; } 

a

public List<Adventurer> Adventurers { get; set; } 

y funciona correctamente para mí.

+0

Gracias por la corrección. Sigo recibiendo el mismo error por alguna razón:/ –

+0

El XmlSerializer simplemente ignoraría cualquier elemento que no esté en el objeto, y como 'City' no está definido en el XML, le asignará el valor 'null' predeterminado. –

2

Primero, la propiedad "Aventureros" no es pública, es inaccesible, creo que la mejor manera de encontrar el error es serializar su objeto y luego comparar el resultado con su archivo xml.

+0

Ahh, buen punto. Me perdí esa. –

1

Pude obtener su xml para deserializar con un par de cambios menores (es decir, el calificador público en Adventurer).

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.IO; 
using System.Xml.Serialization; 

namespace TempSandbox 
{ 
    [XmlRoot] 
    public class Catalog 
    { 
     [XmlElement("Adventurer")] 
     public List<Adventurer> Adventurers; 

     private readonly static Type[] myTypes = new Type[] { typeof(Adventurer), typeof(Gear), typeof(Item) }; 
     private readonly static XmlSerializer mySerializer = new XmlSerializer(typeof(Catalog), myTypes); 

     public static Catalog Deserialize(string xml) 
     { 
      return (Catalog)Utils.Deserialize(mySerializer, xml, Encoding.UTF8); 
     } 
    } 

    [XmlRoot] 
    public class Adventurer 
    { 
     public int ID; 

     public string Name; 

     public string Address; 

     public string Phone; 

     [XmlElement(IsNullable = true)] 
     public Gear Gear; 
    } 

    [XmlRoot] 
    public class Gear 
    { 
     public List<Item> Attack; 

     public List<Item> Defense; 
    } 

    [XmlRoot] 
    public class Item 
    { 
     public string IName; 

     public decimal IPrice; 
    } 
} 

estoy usando [XmlElement ("aventurero")] debido a que los nombres de los elementos XML no coinciden exactamente con los nombres de las propiedades de clase.

NOTA: Estoy usando una herramienta de deserialización genérica que ya tenía a mano.

Cuestiones relacionadas