【问题标题】:List Property Not Being Populated on Deserialisation from XML从 XML 反序列化时未填充列表属性
【发布时间】:2017-07-12 15:44:30
【问题描述】:

我正在尝试将 xml 文件反序列化为 c# 类。我使用在线工具为我生成类,因为 XML 文件的结构非常复杂。除了将重复项填充到主类的 List 属性中之外,这种方法效果很好。

我在 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。

如果有人能指出正确的方向,我将不胜感激。

顺便说一句 - 我知道捕获错误然后抛出它没有任何用处,但我这样做只是为了添加一个断点,这样我就可以查看内部异常(如果有)。一旦我的流程开始工作,我会让错误处理更有意义。

【问题讨论】:

  • 我不确定,但我认为它的发生是因为 没有父级,它代表一个列表。它应该类似于 测试订单 1 测试订单 2
  • @VarunMehta 我试过了,但还是一样
  • 您是否将您的属性和 Xml 元素名称重命名为 Orders ? XmlElement(ElementName = "orders")] public List Orders { get;放; }
  • 由于您无法更改您的 XML,因此此解决方案可能无论如何都不起作用,但会知道问题所在
  • @VarunMehta 我没有这样做,但我现在刚刚尝试过,列表中填充了一个订单项目,但所有属性均为空

标签: c# xml wpf deserialization


【解决方案1】:

问题在于您的 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; }
}

顺便说一句,反序列化代码中的throw e; 可能不是您想要做的(参见this question)。鉴于您实际上并未处理异常,在这种情况下您可以完全删除 try / catch。

您还应该将您的StreamReader 包含在using 块中,以确保在使用后将其丢弃。

【讨论】:

  • 完美——非常感谢!!这就是你去找专家的原因
  • 感谢其他提示 - 它们肯定很有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
  • 2015-10-24
相关资源
最近更新 更多