【问题标题】:Substituting non-existing XML attribute with default value用默认值替换不存在的 XML 属性
【发布时间】:2013-06-16 04:47:48
【问题描述】:

我正在尝试为 XML 文档制作 XML 解析器,其中节点中有一些可选属性,我正在寻找一种优雅的方法,如何解决“对象引用未设置为实例”的问题。 我读过this 主题,非常相似,下面的代码看起来很有前途:

string text = (string) foo.Element("Text") ?? "Default value";

但是,当我尝试实现它时,“对象引用未设置为实例”仍然出现,因此我正在寻找另一种解决方案。这是我拼命努力的一部分。

XML 文件 1:

...
<Message id ="1" appendix = "abc" ></Message>
...

XML 文件 2:

...
<Message id ="2" ></Message>
...

我的解析器(为文件夹中的每个文件循环调用):

public MyNode Parse(string file)
{
    XmlDocument xDoc = new XmlDocument();
    xDoc.Load(file);

    MyNode node = new MyNode();
    node.messageID = (string)xDoc.GetElementsByTagName("Message")[0].Attributes["id"].Value ?? "NULL";
    node.appendix = (string)xDoc.GetElementsByTagName("Message")[0].Attributes["appendix"].Value ?? "NULL";

    return node;
}

你能帮帮我吗?

【问题讨论】:

  • 调试器说什么是空的?
  • ["appendix"] 属性...我得到空引用异常:对象引用未设置为对象的实例。或者可能是属性的值,我不确定。

标签: c# xml xml-parsing


【解决方案1】:

以下 LINQ to XML 查询将返回 MyNode 对象,其中填充了消息 ID 和附录属性的值。如果未找到某些属性,则使用默认值“NULL”:

var xDoc = XDocument.Load(file);
var node = xDoc.Descendants("Message")
               .Select(m => new MyNode {
                   messageID = (string)m.Attribute("id") ?? "NULL",
                   appendix = (string)m.Attribute("appendix") ?? "NULL"
               }).FirstOrDefault();

如果您的 xml 文档中没有 Message 元素,则将返回 null

顺便说一句,当您使用 LINQ to XML 时,使用转换节点到 (string) 比访问其 Value 属性更好。因为如果在文档中找不到节点,那么如果您尝试获取nullValue 属性,那么您将获得NullReferenceException。但是当您将节点转换为string 时,您只需获得null 值而不是异常。这允许您使用 null-coalescing 运算符提供默认值。

【讨论】:

  • 非常感谢您详尽的回答。现在,我对解析过程有了更好的理解。但是,您同事的回答在我的代码中更容易实现(我不得不重新编写更少的代码行),所以我接受了他的回答。
【解决方案2】:

不幸的是,这仅在 Valuenull 时有效,而不是在实际 XAttributenull 时有效。

你必须这样做:

XAttribute temp = xDoc.GetElementsByTagName("Message")[0].Attributes["appendix"];
if (temp == null)
{
    node.appendix = temp.Value;
} 
else
{
    node.appendix = "NULL";
}

【讨论】:

  • 嗯,这是一个可悲的发现……无论如何,非常感谢您的回答。
  • 使用node.appendix = temp == null ? "NULL" : temp.value; 会更好看
猜你喜欢
  • 2019-02-13
  • 2014-03-28
  • 1970-01-01
  • 2012-11-15
  • 2012-06-30
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 2016-02-11
相关资源
最近更新 更多