在“对象未设置”错误之前捕获不存在的XML节点

时间:2012-11-19 16:17:02

标签: c# .net linq xml-parsing linq-to-xml

我有类似于下面的XML。我在C#中使用Linq解析它,它很有效,直到我们找到一个没有type的产品。

<productList>
    <product>
        <type>
            <colour>red</colour>
        </type>
        <name>First</name>
    </product>
    <product>
        <name>Second</name>
    </product>
</productList>

我正在尝试访问colour下的type元素,但当代码到达product但没有type元素时,我得到了“对象引用未设置为对象的实例”错误。

这是我目前用来访问它的代码。我尝试解决这个问题的尝试有点复杂。

productColour = products.Element("type").Descendants().FirstOrDefault() == null ? string.Empty : products.Element("type").Descendants().FirstOrDefault().Value,

我知道colour元素始终是type下的第一个元素,所以我可以使用.FirstOrDefault(),但我仍然会使用此代码获得相同的错误。

有人能指出我正确的方向吗?我也尝试过转换为字符串,最后还有:?? " ",到目前为止都无济于事。

编辑:感谢@ anthony-pegram,看起来问题是我总是试图抓住后代,即使父元素不存在。因此看起来我需要在抓住孩子之前检查父元素 - 有人能指出我的方向吗?

3 个答案:

答案 0 :(得分:3)

Elements()将返回IEnumerable。如果该元素不存在,则IEnumerable将为空并且再次调用Elements将不会产生空引用异常。下面的代码应该从product \ type元素下面拉出颜色而不抛出空引用异常。如果颜色或类型不存在,则返回null。

(string)product.Elements("type").Elements("colour").FirstOrDefault()

答案 1 :(得分:0)

我会在这里使用XPath

var xDoc = XDocument.Parse(xml);
var colour = xDoc.XPathSelectElement("//product/type/colour");
if(colour!=null)
{
    var val = colour.Value;
}

答案 2 :(得分:0)

您是否考虑过使用属性?

<productList>
    <product type="color-red">
        <name>First</name>
    </product>
    <product type="none">
        <name>Second</name>
    </product>
</productList>

无法返回null变量,因为type属性可以具有默认字符串值。我也认为这更整洁,但这是个人偏好。

你也可以<product color="red" />等。