2017-07-12 39 views
0

我想將xml文件反序列化爲c#類。我使用了一個在線工具來爲我生成類,因爲XML文件的結構非常複雜。除了在主類中重複項目的List屬性之外,這種方法運行良好。列表屬性沒有從XML反序列化填充

我在WPF中使用DotNet 4.5,C#。

xml文件的簡化版本如下:

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

,我使用的類是如下:

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

的反序列化代碼如下:

 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(); 

當我運行代碼時,它運行沒有錯誤,但我最終得到一個空的列表。在xml中有其他的結構(沒有重複的結構 - 因此沒有列表屬性)沒有問題,我省略了填充。

我已經看過很多類似於我的問題,但他們似乎提示我正在使用相同的方法。

我無法更改XML,因爲它來自第三方。

如果有人能指出我正確的方向,我將不勝感激。

順便說一句 - 我知道捕獲一個錯誤,然後拋出它是沒有用的,但我只是這樣做,添加一個斷點,所以我可以看看內部的異常,如果有的話。一旦我的流程工作,我會讓錯誤處理更有意義。

+0

我不確定,但我認爲它的發生是因爲代表列表沒有父。它應該像測試訂單1個測試訂單2

+0

@VarunMehta我試過了,但它仍然沒有同樣的事情 – james33

+0

你重命名你的屬性和XML元素名稱到訂單?XmlElement(ElementName =「orders」)] public List Orders {get;組; } –

回答

2

問題是您的Order屬性 - 名稱空間將從OrderMessage繼承,因此它應該爲空時爲urn:gs1:ecom:order:xsd:3。您必須明確指定。

您還可以從模型中刪除一堆與命名空間相關的屬性。這就是你需要:

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

如您deserialisation代碼順便說一句,throw e;可能不是你想要做什麼(見this question)。鑑於你實際上沒有處理異常,你可以在這種情況下完全移除try/catch。

您還應該將StreamReader放在using區塊中以確保它在使用後處置。

+0

完美 - 非常感謝你!這就是爲什麼你去專家 – james33

+0

感謝您的其他技巧 - 他們肯定是有益的 – james33