使用 C# 将 XML 元素的存在反序列化为布尔值

13
我正在尝试将来自Web服务的XML反序列化为C# POCOs。对于我大部分需要的属性,我已经做到了这一点,但是我需要根据元素是否存在设置一个布尔属性,但似乎不知道如何做到这一点?
一个示例XML片段:
<someThing test="true">
    <someThingElse>1</someThingElse>
    <target/>
</someThing>

一个 C# 类的示例:

[Serializable, XmlRoot("someThing")]
public class Something
{
    [XmlAttribute("test")]
    public bool Test { get; set; }

    [XmlElement("someThingElse")]
    public int Else { get; set; }

    /// <summary>
    /// <c>true</c> if target element is present,
    /// otherwise, <c>false</c>.
    /// </summary>   
    [XmlElement("target")]
    public bool Target { get; set; }
}

这只是我处理的实际 XML 和对象层次结构的非常简化的示例,但展示了我试图实现的内容。

我阅读过的所有与反序列化空元素相关的其他问题似乎都涉及使用 Nullable<T>,但这不是我需要的。

有人有什么想法吗?

2个回答

15

一种方法是使用不同的属性来获取元素的值,然后使用Target属性来确定该元素是否存在。如下所示。

[XmlElement("target", IsNullable = true)]
public string TempProperty { get; set; }

[XmlIgnore]
public bool Target
{
    get
    {
        return this.TempProperty != null;
    }
}

即使存在空元素,TempProperty也不会为空,所以如果<target />存在,Target将返回true


谢谢,我想太多了 :) - James Simm

0

你能解释一下为什么不想使用可空类型吗?
当你在 POCO 中定义一个 int (而不是 int? )属性时,它并不真正表示底层的 xml,你只会得到这些变量的默认值。
如果你假设在你的 xml 中不会出现空字符串或整数值为 0 的情况,那么你可以为每个属性使用 Balthy 建议的方法,或者 使用此处描述的方法


通常我认为更好的做法是创建一个描述你的 xml 的模式,并基于该模式生成类,同时使用可空类型,如果你确实希望你的类代表底层数据。


我正在对来自Google搜索设备的结果进行反序列化。如果结果被自动过滤,则在<RES>元素中存在一个<FI/>元素,否则不存在。我需要设置一个属性来指示结果集是否已过滤 - 我不知道可空布尔值如何在这种情况下有所帮助? - James Simm
在这种情况下使用的可空对象是针对属性本身而不是标记其是否为空/ null的布尔值的。如果你不关心FI的内容,只想检查它是否存在,则Balthys方法可以胜任。当您想要检查的值为数字或其他在使用类实例时将获得默认非空值的值时,应使用Nullable属性,以用于更高级的场景。 例如,如果<FI>是数值类型,如整数,并且您在类中使用int FI,它将始终具有值0,这与null不同。 - YavgenyP
谢谢,我明白 Nullable 的作用。然而,在这种情况下,它们与使用 Balthy 建议的简单 null 检查没有什么区别。<FI/> 元素从来没有值——它只是表示某个东西的存在。因此,Nullable<T> 的值始终为 default(T) 或 null。 - James Simm

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