2009-09-14 18 views
11

Ho un file xml piuttosto dettagliato. Di seguito è riportato i nodi di livello superiore (ho incluso l'ellisse come i nodi di livello inferiore sono tutti ben formato e debitamente compilato con i dati):Problemi con la deserializzazione XML nelle classi generate da XSD

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

ho creato un file XSD di utilizzare il prompt dei comandi di Visual Studio 2008:

xsd sample.xml 

Questo genera il file XSD bene. Ho poi automaticamente generare classi dal XSD con il comando:

xsd sample.xsd /classes 

Per la deserializzazione del file XML in un oggetto di classe, sto usando la funzione di lettura nella classe helper:

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

quando si tenta la deserializzazione con:

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

ricevo un errore che ho dedotto è perché il deserializzatore è alla ricerca per il nodo 'modelli' ma il nome corrispondente classe era generat ed come combinazione del nodo radice e del nodo 'Modello' (configModels). Perché i nomi delle classi vengono generati in questo modo?

ho cercato di deserializzare dal nodo superiore utilizzando:

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

Purtroppo, questo i risultati in una sfilza di errori come il seguente:

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. 

qualcuno può orientare verso quello che potrebbe si sta comportando male con il mio xsd auto-generatore?

+0

Nessuno degli strumenti automatici produrrebbe il codice corretto. Ho scritto a mano il codice oggetto per il xml per deserializzare in. –

+0

Potresti per favore segnare la risposta di marc_s come corretta visto che hai detto che ha risolto il tuo problema? – Win

risposta

3

C'è un problema con xsd.exe ed elenchi. Devi andare nella classe generata e modificare manualmente il file nel tipo corretto. Sono passato a usare Xsd2Code. Finora non sembra avere questo problema.

+0

Ho appena provato Xsd2Code e anch'io mi sta dando gli stessi errori di conversione con gli elenchi. –

+0

Non dovrei usare xsd.exe per generare automaticamente il file xsd? –

+0

Si può usare bene. Devi semplicemente andare nella classe generata e modificarla a mano. Tuttavia, se Xsd2Code avesse problemi, dovrei essere d'accordo con @marc_s; è probabilmente qualcosa nel tuo schema xml che sta causando il problema. –

10

XSD.EXE è un buon inizio, ma è tutt'altro che perfetto. Inoltre, in base all'XML fornito, XSD.EXE non può sempre decidere con certezza se qualcosa è una singola istanza di un oggetto o una matrice di oggetti aperta.

questo sembra essere il caso per le tue due elementi - Application.Lease e Application.CashFlow. Come sono definiti nel file XSD generato? Ha senso per te? Molto probabilmente, dovreste aggiungere un po 'di suggerimenti, come ad esempio:

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

per una proprietà facoltativa, questo è solo zero o uno occorrenze. Cose del genere sono davvero difficili da trovare per lo strumento xsd.exe basandosi solo su un singolo file di esempio XML.

Marc

+1

Marc, hai ragione sui soldi lì, la tua soluzione ha risolto il problema per me. L'aggiornamento manuale dei valori minOccurs e maxOccurs sugli elementi offendenti, quindi l'esecuzione di XSD2CODE per generare le mie classi, ha risolto il problema per me. – ProNotion

10

Vai alla classe generata e cambiare tutto da [] [] ---> []

+0

Mentre questo risolverà il problema, la risposta di marc_s fornisce una spiegazione del perché è necessario e di come evitare di doverlo fare. – MyItchyChin

0

Un altro problema che può causare questo problema è che il contenuto del file XML tra i tag (che significa il contenuto) è ancora codificato quando non dovrebbe essere. Ad esempio, i tag <br> nel mio contenuto erano ancora <br> anziché &lt;br /&gt;. Il generatore xsd li ha trasformati in elementi nello schema e li ha erroneamente etichettati come illimitati poiché ne sono stati trovati più di uno.Unencoding li ha risolto il problema e generato correttamente le classi.

Problemi correlati