如何在不出现空异常的情况下使用 linq2Xml?
我编写了这个简单的 linq-to-xml 查询,似乎使用 linq 语法无法避免 null 异常。难道是我用错了?正确(且简短)的 Linq2Xml 语法应该是什么?
linq2Xml 查询
var userData =
queryUserResponseData.Elements("user")
.Single(u => u.Element("username").Value == userName);
XML
<data>
<user>
<username>User1</username>
<userid>123</userid>
</user>
<user>
<username>User2</username>
<userid>456</userid>
</user>
<user>
<userid>999</userid>
</user>
</data>
I wrote this simple linq-to-xml query and it seems that null exception could not be avoided using the the linq syntax. Am I using it wrong? What should be the right (and short) Linq2Xml syntax?
The linq2Xml query
var userData =
queryUserResponseData.Elements("user")
.Single(u => u.Element("username").Value == userName);
The XML
<data>
<user>
<username>User1</username>
<userid>123</userid>
</user>
<user>
<username>User2</username>
<userid>456</userid>
</user>
<user>
<userid>999</userid>
</user>
</data>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
XElement 和 XAttribute 有一些显式转换运算符将它们的值转换为特定类型。它们非常有用,因为当元素或属性丢失时返回 null。
XElement and XAttribute have some explicit conversion operators to convert their value to the specific types. They are so useful because, return null when the Element or Attribute is missing.
从您对艾哈迈德·马吉德的回答的评论:
听起来您可能担心的是潜在问题而不是真正的问题。您知道您的数据意味着您将始终返回 1 个结果,但是 ReSharper 无法访问您的数据,因此它强调了这样一个事实:如果没有结果,它将生成空引用异常。
您可以执行以下三件事之一:
忽略警告,不执行任何操作。
重新编码以解决此问题,以便不会出现异常(请参阅其他答案)。
将 Linq 封装在
try {} catch {}
中,这样,如果发生“不可想象的”情况,您的程序就不会崩溃。只有你才能真正决定你想做什么。
From your comment to Ahmad Mageed's answer:
it sounds like you might be worrying about a potential rather than real problem. You know that your data will mean that you will always return 1 result, however ReSharper doesn't have access to your data so it's highlighting the fact that if there were no results it would generate a null reference exception.
You can do one of three things:
Ignore the warning and do nothing.
Recode to account for this so that there's no chance of an exception (see the other answers).
Wrap the Linq in a
try {} catch {}
so that if the "unthinkable" happens your program won't crash.Only you can really decide which you want to do.
使用
Single
意味着您预计只有 1 个结果。当返回更多结果时,Single 会抛出异常。您可以使用First
获取第一项,或使用Last
获取最后一项。对于多个项目,您需要循环结果并单独访问每一项。如果不存在匹配结果,您可以使用
SingleOrDefault
返回null
值或所使用类型的默认值。queryUserResponseData
是 XElement 还是 XDocument?如果它是 XDocument,您需要首先访问 XML 的根,例如:除此之外,在示例中搜索 User1 或 User2 也可以。但是,如果您搜索不存在的User3,则 Single 将引发异常。在这种情况下,您应该使用 SingleOrDefault:
Using
Single
means you expect there to be exactly 1 result. When more results are returned, Single will throw an exception. You could useFirst
to get the first item, orLast
for the last one. For multiple items you'll want to loop over the results and access each one individually.If no matching result exists, you can use
SingleOrDefault
to return anull
value or the default value of the type used.Is
queryUserResponseData
an XElement or an XDocument? If it's an XDocument you need to access the XML's root first, such as:Apart from that, searching for User1 or User2 in your sample would work. However, if you searched for User3, which doesn't exist, Single will throw an exception. In that case you should use SingleOrDefault:
根据您对艾哈迈德答案的评论,我认为当元素没有节点时您会得到 NullReferenceException。您可以这样修复它 -
但如果 DTD 或 XSD 需要用户名节点,或者您确定所有元素都有用户名节点,您可以简单地忽略 ReSharper 警告。
According to your comment to Ahmad's answer, I presume you get NullReferenceException when element doesn't have node. You can fix it like this -
But if username node is required there by DTD or XSD or you are sure all elements will have username node, you can simply ignore ReSharper warning.