2017-07-12 1 views
0

Ich versuche, eine XML-Datei in C# -Klassen zu deserialisieren. Ich habe ein Online-Tool verwendet, um die Klassen für mich zu generieren, da die Struktur der XML-Datei sehr komplex ist. Dies funktionierte gut, mit Ausnahme der Population von wiederholten Elementen in einer List-Eigenschaft in der Hauptklasse.List-Eigenschaft, die bei Deserialisierung von XML nicht ausgefüllt wird

Ich verwende DotNet 4.5, C# in WPF.

Eine vereinfachte Version der XML-Datei lautet wie folgt:

<orderMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:gs1:ecom:order:xsd:3"> 
    <order xmlns=""> 
    <creationDateTime>2017-07-10T00:00:00</creationDateTime> 
    <documentStatusCode>ORIGINAL</documentStatusCode> 
    <documentActionCode>ADD</documentActionCode> 
    </order> 
    <order xmlns=""> 
    <creationDateTime>2017-07-10T00:00:00</creationDateTime> 
    <documentStatusCode>ORIGINAL</documentStatusCode> 
    <documentActionCode>ADD</documentActionCode> 
    </order> 
</orderMessage> 

Die Klassen, die ich wie unten bin mit:

[XmlRoot(ElementName = "order")] 
public class Order 
{ 
    [XmlElement(ElementName = "creationDateTime")] 
    public string CreationDateTime { get; set; } 
    [XmlElement(ElementName = "documentStatusCode")] 
    public string DocumentStatusCode { get; set; } 
    [XmlElement(ElementName = "documentActionCode")] 
    public string DocumentActionCode { get; set; } 
    [XmlAttribute(AttributeName = "xmlns")] 
    public string Xmlns { get; set; } 
} 

[XmlRoot(ElementName = "orderMessage", Namespace = "urn:gs1:ecom:order:xsd:3")] 
public class OrderMessage 
{ 
    [XmlElement(ElementName = "order")] 
    public List<Order> Order { get; set; } 
    [XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")] 
    public string Xsd { get; set; } 
    [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")] 
    public string Xsi { get; set; } 
    [XmlAttribute(AttributeName = "xmlns")] 
    public string Xmlns { get; set; } 
} 

Die Deserialisierung Code lautet wie folgt:

 XmlSerializer serializer = new XmlSerializer(typeof(OrderMessage)); 

     StreamReader reader = new StreamReader(filename); 
     OrderMessage newOrderMessage; 
     try 
     { 
      newOrderMessage = (OrderMessage)serializer.Deserialize(reader); 
     } 
     catch (Exception e) 
     { 
      throw e; 
     } 
     reader.Close(); 

Wenn ich den Code ausführen, läuft es ohne Fehler, aber ich am Ende mit einer leeren Liste. Es gab andere Strukturen in der XML-Datei (die keine wiederholten Strukturen waren - daher keine Listen-Eigenschaft), die ohne Probleme gefüllt wurden, die ich weggelassen habe.

Ich habe mir eine Reihe von Fragen angesehen, die meinen ähneln, aber sie scheinen die gleiche Methode vorzuschlagen, die ich verwende.

Ich kann das XML nicht ändern, wie es von einer dritten Partei ist.

Ich würde es sehr schätzen, wenn mir jemand in die richtige Richtung zeigen könnte.

BTW - Ich weiß, dass ein Fehler zu fangen und dann zu werfen ist nutzlos, aber ich habe nur das getan, um einen Haltepunkt hinzuzufügen, damit ich die inneren Ausnahmen betrachten konnte, wenn es welche gab. Ich werde die Fehlerbehandlung sinnvoller machen, sobald der Prozess funktioniert.

+0

Ich bin mir nicht sicher, aber ich denke, dass es passiert, weil es kein Elternteil zu der gibt, die eine Liste darstellt. Es sollte so etwas wie Prüfauftrag 1 Prüfauftrag 2

+0

@VarunMehta sein habe ich versucht, dass aber es hat immer noch die gleiche Sache – james33

+0

Haben Sie Ihr Eigentum und XML Element Name auf Bestellungen umbenennen?XmlElement (ElementName = "orders")] öffentliche Liste Orders {get; einstellen; } –

Antwort

2

Das Problem ist Ihre Order -Eigenschaft - der Namespace wird von OrderMessage vererbt, so ist es urn:gs1:ecom:order:xsd:3, wenn es leer sein sollte. Sie müssen dies explizit angeben.

Sie können auch eine Reihe von Namensraumattributen aus Ihrem Modell entfernen. Das ist alles, was Sie brauchen:

[XmlRoot("orderMessage", Namespace = "urn:gs1:ecom:order:xsd:3")] 
public class OrderMessage 
{ 
    [XmlElement("order", Namespace = "")] 
    public List<Order> Orders { get; set; } 
} 

public class Order 
{ 
    [XmlElement("creationDateTime")] 
    public string CreationDateTime { get; set; } 

    [XmlElement("documentStatusCode")] 
    public string DocumentStatusCode { get; set; } 

    [XmlElement("documentActionCode")] 
    public string DocumentActionCode { get; set; } 
} 

Als beiseite, throw e; in Ihrem Deserialisation Code ist wahrscheinlich nicht das, was Sie (siehe this question) tun wollen. Wenn Sie die Ausnahme nicht wirklich behandeln, können Sie die try/catch in diesem Fall vollständig entfernen.

Sie sollten auch Ihren StreamReader in einem using Block einschließen, um sicherzustellen, dass er nach der Verwendung entsorgt wird.

+0

Perfekt - vielen Dank !! Deshalb gehen Sie zu den Experten – james33

+0

Danke für die anderen Tipps - sie sind sicherlich hilfreich – james33