2013-02-08 22 views
5

Próbuję deserializowania następujące XML:deserializacji XML zwraca null dla właściwości zbierania

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

Korzystanie z następujących klas:

[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 

ale bez względu na to, co staram, jest tablica CurrentAccounts null, gdy deserializuję to. Próbowałem każdej kombinacji, którą mogę wymyślić z atrybutami (wypróbowałem XmlArray i XmlArrayItem też).

Co robię źle? : S

+0

Przepraszamy, zaktualizowano pytanie za pomocą kodu deserializacji. – Tom

+0

Czy nie ma potrzeby oznaczania klas za pomocą "[Serializable()]"? – Nope

+0

@ François Próbowałem tego, ale najwyraźniej to nie jest potrzebne. – Tom

Odpowiedz

2

problem jest z przestrzeniami nazw.

Kiedy stworzyłem całą konfigurację klasy w sytuacji testowej, otrzymałem zupełnie inny wygląd. tutaj jest to, co myślę, że należy starać się czytać:

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

Wskazówka wszystkie dodatkowe mf:. Po zadeklarowaniu przestrzeni nazw, serializator będzie działał z tym i usunie szeregowanie węzłów, które właściwie należą do tej przestrzeni nazw. Musisz albo całkowicie się go pozbyć, albo odpowiednio poprawić swój wkład. Oto kod, który służy do generowania to wyjście uwaga: definicje klasy są całkowicie niezmieniona

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

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

i podczas czytania go z powrotem:

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

po uruchomieniu obu odcinków, b jest teraz doskonały klon a, a xml, który pokazałem powyżej, to wygenerowany xml.

+0

Dzięki za to. Niestety XML pochodzi od strony trzeciej, więc nie mam nad nią kontroli. Próbowałem dodać to do właściwości CurrentAccounts: '[XmlElement (" CurrentAccount ", Namespace =" urn: somedata ")]' ale bez skutku. – Tom

+0

Czy można edytować plik XML przed próbą deserializacji? Jeśli użyjesz jakiegoś Regexa na tym pierwszym wierszu i wyeliminujesz "mf:" z górnego węzła, to będziesz miał jednolity classdef i powinien poprawnie deserializować ... – Nevyn

+1

@ Czy próbowałeś [XmlElement ("CurrentAccount", Namespace = String.Empty)]? – jbl

0

Może powinieneś spróbować wymienić swoją klasę MfCurrentAccounts z:

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

} 

lub dać do obejrzenia https://stackoverflow.com/a/364410/1236044

nadzieję, że to pomoże

+0

To po prostu zwraca pustą listę. :(Będę się z nim bawił, ponieważ wygląda na to, że powinien zadziałać. Spróbuję napisać na dysk i użyć pliku XSD, ale wolałbym nie podążać tą drogą. – Tom

+0

@Tom klasa może potrzebować publicznego konstruktora. Zaktualizowałem moją odpowiedź: – jbl

+0

To też nie działa, ale twój komentarz na temat poprzedniej odpowiedzi działa. :) – Tom