【问题标题】:Xml Empty Tag DeserializationXml 空标签反序列化
【发布时间】:2016-06-20 20:49:25
【问题描述】:

你能帮我找到反序列化包含空标签的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 中的行的异常。

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

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

【问题讨论】:

    标签: c# xml serialization


    【解决方案1】:

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

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

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

    <ItemsCount xs:Nil='true'/>
    

    【讨论】:

      【解决方案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);
      }
      

      【讨论】:

      • 这是最优雅的解决方案。另一种可能的方式可能是使用e.Element.IsEmpty 而不是e.Element.InnerText == string.Empty
      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-26
        • 1970-01-01
        • 2015-05-19
        • 1970-01-01
        • 1970-01-01
        • 2021-08-07
        相关资源
        最近更新 更多