XML空标签反序列化

3

您能帮助我找到反序列化包含空标签的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个回答

2

XmlSerializer试图将标签的string.Empty值转换为整数并失败。请按照以下方式更改属性以将数据类型转换为字符串:

```csharp public string YourProperty { get; set; } = 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);
}

1
这是最优雅的解决方案。另一种可能的方法是使用 e.Element.IsEmpty 而不是 e.Element.InnerText == string.Empty - Yusef Maali

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接