2013-02-08 11 views
5

Sto cercando di deserializzare il seguente codice XML:deserializzazione XML restituisce null per la proprietà raccolta

<?xml version="1.0" encoding="utf-8" ?> 
<mf:somedata xmlns:mf="urn:somedata"> 
    <CurrentAccount> 
     <AccountType>test</AccountType> 
     <Charge> 
      <ChargeType>test</ChargeType> 
     </Charge> 
    </CurrentAccount> 
    <CurrentAccount> 
     <AccountType>test 2</AccountType> 
     <Charge> 
      <ChargeType>test 2</ChargeType> 
     </Charge> 
    </CurrentAccount> 
</mf:somedata> 

usando le seguenti classi:

[XmlRoot("somedata", Namespace = "urn:somedata")] 
public class MfCurrentAccounts 
{ 
    [XmlElement("CurrentAccount")] 
    public CurrentAccount[] CurrentAccounts { get; set; } 
} 

public class CurrentAccount 
{ 
    public string AccountType { get; set; } 

    [XmlElement("Charge")] 
    public Charge[] Charges { get; set; } 
} 

public class Charge 
{ 
    public string ChargeType { get; set; } 
} 

var c = new XmlSerializer(typeof(MfCurrentAccounts)).Deserialize(new StringReader(xml)) as MfCurrentAccounts; 

c.CurrentAccounts // <-- is always null 

Ma non importa quello che provo, la matrice è CurrentAccounts null quando lo deserializzo. Ho provato ogni combinazione che posso immaginare con gli attributi (ho provato anche XmlArray e XmlArrayItem).

Cosa sto sbagliando? : S

+0

Siamo spiacenti, ha aggiornato la domanda con il codice di deserializzazione. – Tom

+0

Non è necessario contrassegnare le classi con '[Serializable()]'? – Nope

+0

@ François L'ho provato, ma a quanto pare non è necessario. – Tom

risposta

2

Il problema è con spazi dei nomi.

Quando ho creato l'intera installazione di classe in una situazione di test, ho ottenuto un risultato molto diverso. qui è quello che penso si dovrebbe cercare di leggere in:

<?xml version="1.0"?> 
    <mf:somedata xmlns:mf="urn:somedata"> 
     <mf:CurrentAccount> 
      <mf:AccountType>something 1</mf:AccountType> 
      <mf:Charge> 
       <mf:ChargeType>Charge Type 1</mf:ChargeType> 
      </mf:Charge> 
     </mf:CurrentAccount> 
     <mf:CurrentAccount> 
      <mf:AccountType>something 2</mf:AccountType> 
      <mf:Charge> 
       <mf:ChargeType>Charge Type 2</mf:ChargeType> 
      </mf:Charge> 
     </mf:CurrentAccount> 
    </mf:somedata> 

preavviso tutte le più mf:. Quando si dichiara lo spazio dei nomi, il serializzatore funzionerà con quello e decodificherà solo i nodi che appartengono propriamente a tale spazio dei nomi. O hai bisogno di sbarazzartene interamente o aggiustare il tuo input in modo appropriato. Ecco il codice che ho usato per generare quella nota uscita : le definizioni di classe sono completamente invariati

XmlSerializer ser = new XmlSerializer(typeof(MfCurrentAccounts)); 
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
ns.Add("mf", "urn:somedata"); 

MemoryStream ms = new MemoryStream(); 
ser.Serialize(ms, a, ns); 

e durante la lettura indietro in:

ms.Position = 0; 
b = ser.Deserialize(ms) as MfCurrentAccounts; 

dopo l'esecuzione di entrambe le sezioni, b è ora un clone perfetto di a, e l'xml che ho mostrato sopra è l'xml generato.

+0

Grazie per quello. Sfortunatamente l'XML proviene da una terza parte, quindi non ne ho il controllo. Ho provato ad aggiungere questo alla proprietà CurrentAccounts: '[XmlElement (" CurrentAccount ", Namespace =" urna: somedata ")]' ma senza successo. – Tom

+0

È possibile modificare l'xml prima di tentare di deserializzarlo? Se usi un certo Regex su quella prima riga ed elimini "mf:" dal nodo superiore, allora avrai un classdef uniforme e dovrebbe deserializzare correttamente ... – Nevyn

+1

@Tom hai provato [XmlElement ("CurrentAccount", Namespace = String.Empty)]? – jbl

0

Forse si dovrebbe provare a sostituire la classe MfCurrentAccounts con:

[XmlRoot("somedata", Namespace = "urn:somedata")] 
public class MfCurrentAccounts : List<CurrentAccount> 
{ 
    public MfCurrentAccounts():base() 
    {} 

} 

o dare un'occhiata a https://stackoverflow.com/a/364410/1236044

Spero che questo vi aiuterà

+0

Questo restituisce solo una lista vuota. :(Ci giocherò comunque, perché sembra che dovrebbe funzionare. Daremo un'occhiata alla scrittura su disco e all'utilizzo di un file XSD, ma preferirei non seguire questa strada. – Tom

+0

@Tom la classe potrebbe aver bisogno di un costruttore pubblico Ho aggiornato la mia risposta – jbl

+0

Anche quella non sembra funzionare, ma il tuo commento sulla risposta precedente funziona :) – Tom

Problemi correlati