Xml空标记反序列化

时间:2016-06-20 11:47:06

标签: c# xml serialization

您能否帮我找一个反序列化包含空标记的xml文件的解决方案?

示例在这里:

<Report>
    <ItemsCount></ItemsCount>
</Report>

我想将它反序列化为类的对象:

public class Report{
    public int? ItemsCount { get;set;}
}

我在反序列化中使用的xml架构是:

[XmlRoot]
public partial class Report
{
   private int? itemsCount;

   [XmlElement(IsNullable = true)]
   public int? ItemsCount {
      get
      {
           return itemsCount;
      }
      set
      {
           itemsCount = value;
      }
}

如果ItemsCount标记完全丢失,它会很好用,但是如果它存在且同时为空,那么它会抛出关于这个标记位于xml中的行的异常。

我在尝试寻找解决方案时看到了很多链接,但没有成功。

而且,我不想忽略所有情况的标记,我想得到一个空值而不是它是空的。

3 个答案:

答案 0 :(得分:2)

XmlSerializer正在尝试将tag的string.Empty值转换为整数并失败。如下所示更改您的属性以将数据类型转换为字符串:

[XmlElement]
public string ItemsCount {
      get
      {
           return itemsCount;
      }
      set
      {
           itemsCount = value;
      }

在上述情况下,这会将属性Itemscount设置为空。 对于上述属性的null值,xml应如下所示:

<ItemsCount xs:Nil='true'/>

答案 1 :(得分:2)

这种做法怎么样?

按如下方式定义类:

public class Report
{
    [XmlIgnore]
    public int? ItemsCount { get; set; }
}

由于XmlIgnore属性,此标记将被视为未知 创建序列化程序时添加事件处理程序:

var xs = new XmlSerializer(typeof(Report));
xs.UnknownElement += Xs_UnknownElement;

在事件处理程序中将空字符串解释为null:

private void Xs_UnknownElement(object sender, XmlElementEventArgs e)
{
    var report = (Report)e.ObjectBeingDeserialized;

    if (e.Element.InnerText == string.Empty)
        report.ItemsCount = null;
    else
        report.ItemsCount = int.Parse(e.Element.InnerText);
}

像往常一样使用序列化程序:

Report report;
using (var fs = new FileStream("test.xml", FileMode.Open))
{
    report = (Report)xs.Deserialize(fs);
}

答案 2 :(得分:1)

据我了解,所描述的行为是正确的;如果标记ItemsCount缺失,则其值为null;如果为空,则无法将其值从""转换为值int?。话虽这么说,可以在ItemsCount的访问器中实现一些自定义解析,这些访问器必须是string类型。但是,这似乎更像是一种解决方法。如果可能,应将文档更改为开头。