我正在尝试将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,因为它来自第三方。
如果有人能指出我正确的方向,我将不胜感激。
BTW - 我知道捕获一个错误然后抛出它是没有用的,但我只是添加一个断点,所以我可以查看内部异常,如果有的话。一旦我的流程正常工作,我将使错误处理更有意义。答案 0 :(得分: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; }
}
顺便说一句,您的反序列化代码中的throw e;
可能不是您想要做的(请参阅this question)。鉴于您实际上没有处理异常,在这种情况下您可以完全删除try / catch。
您还应将StreamReader
括在using
块中,以确保在使用后将其处理。