将 XElement 转换为 int?指定 xsi:nil = "true" 时失败

Casting XElement to int? fails when xsi:nil = "true" is specified

XElement 明确支持转换为 Nullable,但它没有像我预期的那样工作。以下单元测试演示了该问题:

    [TestMethod]
    public void CastingNullableInt()
    {
        var xdoc = XDocument.Parse("<root xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><okay>123</okay><boom xsi:nil=\"true\"/></root>");
        Assert.AreEqual(123, (int?)xdoc.Root.Element("okay"));
        Assert.IsNull((int?)xdoc.Root.Element("boom"));
    }

测试应该通过最后一个断言。相反,它给出了 FormatException:

Input string was not in a correct format.

为什么这里不能正确解析为 null

XElement 没有正确解析 <boom xsi:nil=\"true\"/>。它仅在您省略 <boom xsi:nil=\"true\"/> 时有效,然后值为 null 并且它 returns (int?)null.

解决方法可能是首先检查值是否为空:

!string.IsNullOrEmpty((string)xdoc.Root.Element("boom"))
    ? (int?)xdoc.Root.Element("boom")
    : null
    ;

Linq to XML 不支持架构,因此它不会将 xsi:nil = "true" 转换为可为 null 的变量。要对此进行测试,您需要执行以下操作:

Assert.IsTrue((bool?)xdoc.Root.Element("boom").Attribute("{http://www.w3.org/2001/XMLSchema-instance}nil") == true);

你可以查看IsEmpty 属性:

var value = xdoc.Root.Element("boom").IsEmpty ? null : (int?)xdoc.Root.Element("boom");