2017-07-12 36 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