【问题标题】:Catching non-existent XML nodes before "object not set" error在“未设置对象”错误之前捕获不存在的 XML 节点
【发布时间】:2012-11-07 14:42:26
【问题描述】:

我有一些类似于下面的 XML。我在 C# 中使用 Linq 对其进行解析,它运行良好,直到我们得到一个没有 type 的产品。

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

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

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

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

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

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

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

【问题讨论】:

  • 当你说Elements("type").Descendants(),并且没有“type”元素时,你会得到一个错误。您需要在查询其后代之前处理缺少的元素。到目前为止,您的尝试是处理丢失的后代,但那是在您的问题已经呈现出丑陋的头之后。
  • 感谢您的评论 - 您知道如何使用 Linq 解决这个问题吗?

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


【解决方案1】:

Elements() 将返回一个 IEnumerable。如果该元素不存在,则 IEnumerable 将只是空的,并且在其上再次调用 Elements 不会产生空引用异常。下面的代码应该从 product\type 元素下提取颜色,而不会引发空引用异常。如果颜色或类型不存在,则返回 null。

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

【讨论】:

  • 使用“元素”而不是“元素”?
  • 这可能是你能做的最好的编辑。看起来效果很好 - 非常感谢!
  • 没问题,很高兴能帮上忙 :)
【解决方案2】:

我会在这里使用 XPath

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

【讨论】:

    【解决方案3】:

    你有没有想过使用属性来代替?

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

    不可能返回一个空变量,因为类型属性可以有一个默认的字符串值。我也认为这样更整洁,但这是个人喜好。

    您也可以使用&lt;product color="red" /&gt; 等。

    【讨论】:

    • 当然更整洁,但不幸的是,在这种情况下,我无法控制 XML 源。不过还是谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 2020-01-03
    • 2017-08-26
    • 2018-01-06
    • 2014-07-02
    相关资源
    最近更新 更多