2009-09-14 9 views
11

Tengo un archivo XML bastante detallado. A continuación se muestra los nodos de nivel superior (He incluido la elipse como los nodos de nivel inferior son todos bien formado y llenado correctamente con los datos):Problema con la deserialización de XML en clases generadas por XSD

<?xml version="1.0" encoding="UTF-8"?> 
<config> 
    <Models>...</Models> 
    <Data>...</Data> 
</config> 

He creado un archivo xsd de utilizar el símbolo de Visual Studio 2008:

xsd sample.xml 

Esto genera el archivo xsd muy bien. Entonces auto generar clases desde el xsd con el comando:

xsd sample.xsd /classes 

Para la deserialización del archivo XML en un objeto de clase, estoy usando la función de lectura en la clase de ayuda:

public class XmlSerializerHelper<T> 
{ 
    public Type _type; 

    public XmlSerializerHelper() 
    { 
     _type = typeof(T); 
    } 

    public void Save(string path, object obj) 
    { 
     using (TextWriter textWriter = new StreamWriter(path)) 
     { 
      XmlSerializer serializer = new XmlSerializer(_type); 
      serializer.Serialize(textWriter, obj); 
     } 
    } 

    public T Read(string path) 
    { 
     T result; 
     using (TextReader textReader = new StreamReader(path)) 
     { 
      XmlSerializer deserializer = new XmlSerializer(_type); 
      result = (T)deserializer.Deserialize(textReader); 
     } 
     return result; 
    } 
} 

al intentar la deserialización con:

var helper = new XmlSerializerHelper<configModels>(); 
var obj = new configModels(); 
obj = helper.Read(filepath); 

recibo un error que he deducido es debido a que el deserializer está buscando el nodo de 'modelos', pero el nombre de la clase correspondiente se ge ed como una combinación del nodo raíz y el nodo 'Modelo' (configModels). ¿Por qué los nombres de clase se generan así?

Me trataron de deserializar desde el nodo superior usando:

var helper = new XmlSerializerHelper<config>(); 
var obj = new config(); 
obj = helper.Read(filepath); 

Desafortunadamente, esto los resultados en una serie de errores como el siguiente:

System.InvalidOperationException was unhandled by user code 
Message="Unable to generate a temporary class (result=1). 
error CS0030: Cannot convert type 'Application.Lease[]' to 'Application.Lease' 
error CS0030: Cannot convert type 'Application.CashFlow[]' to 'Application.CashFlow' 
...ect. 

alguien puede dirigir hacia lo que podría estar haciendo mal con mi auto-generación xsd?

+0

Ninguna de las herramientas automatizadas produciría el código correcto. A mano escribí el código objeto para el xml para deserializar en. –

+0

¿Podría marcar la respuesta de marc_s como correcta ya que dijo que resolvió su problema? – Win

Respuesta

3

Hay un problema con xsd.exe y listas. Debe ingresar a la clase generada y editar manualmente el archivo al tipo correcto. Cambié a usar Xsd2Code. Hasta ahora no parece tener este problema.

+0

Acabo de probar Xsd2Code y también me está dando los mismos errores de conversión con las listas. –

+0

¿No debería usar xsd.exe para generar automáticamente el archivo xsd? –

+0

Puedes usarlo bien. Simplemente tiene que ir a la clase generada y editarla a mano. Sin embargo, si Xsd2Code también tuviera problemas, tendría que estar de acuerdo con @marc_s; es probable que algo en su esquema xml sea el causante del problema. –

10

XSD.EXE es un buen comienzo, pero está lejos de ser perfecto. Además, en función del XML que proporcionó, XSD.EXE no siempre puede decidir con certeza si algo es una instancia única de un objeto o una matriz de objetos abiertos.

Este parece ser el caso de sus dos elementos: Application.Lease y Application.CashFlow. ¿Cómo se definen en el archivo XSD generado? ¿Eso tiene sentido para ti? Muy posiblemente, habría que añadir un poco de consejos, tales como:

<xs:element name="Lease" minOccurs="0" maxOccurs="1" /> 

de una propiedad opcional, eso es sólo una o ninguna ocurrencias. Cosas como esa son realmente difíciles de descifrar para la herramienta xsd.exe en base a un solo archivo de muestra XML.

Marc

+1

Marc, tienes razón en el dinero allí, tu solución resolvió el problema para mí. Actualizar manualmente los valores de minOccurs y maxOccurs en los elementos ofensivos y luego ejecutar XSD2CODE para generar mis clases resolvió este problema para mí. – ProNotion

10

Vaya a su clase generada y cambiar todo desde [] [] ---> []

+0

Si bien esto solucionará el problema, la respuesta de marc_s proporciona una explicación de por qué es necesario y cómo evitar tener que hacer esto. – MyItchyChin

0

Otro problema que puede causar este problema es que el contenido del archivo XML entre las etiquetas (es decir, el contenido) todavía está codificado cuando no debería ser. Por ejemplo, las etiquetas <br> en mi contenido todavía eran <br> en lugar de &lt;br /&gt;. El generador de xsd los convirtió en elementos en el esquema y los etiquetó erróneamente como ilimitados ya que se encontraron más de uno.Desconectarlos resolvió el problema y generó las clases correctamente.

Cuestiones relacionadas