簡體   English   中英

如何使用linq2Xml沒有null異常的可能性?

[英]How to use linq2Xml without the possibility of a null exception?

我寫了這個簡單的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>

XElement和XAttribute有一些顯式轉換運算符,可將其值轉換為特定類型。 它們非常有用,因為當元素或屬性丟失時返回null。

var userData = queryUserResponseData.Elements("user").Single(u => (string)u.Element("username") == userName);

從您對Ahmad Mageed的回答的評論:

問題實際上是u.Element("username").Value Resharper通知我有關可能的null異常的值

聽起來你可能會擔心潛在的而不是真正的問題。 您知道您的數據將意味着您將始終返回1個結果,但是ReSharper無法訪問您的數據,因此它突出顯示如果沒有結果則會生成空引用異常。

你可以做以下三件事之一:

  1. 忽略警告,什么都不做。

  2. 重新編碼以解決此問題,以便不存在異常的可能性(請參閱其他答案)。

  3. 將tryq包裹在try {} catch {}這樣如果“不可想象”發生,你的程序就不會崩潰。

只有你才能真正決定你想做什么。

使用Single意味着您可以獲得恰好1個結果。 返回更多結果時,Single將拋出異常。 您可以使用First來獲取第一個項目,或者使用Last來獲取最后一個項目。 對於多個項目,您需要循環遍歷結果並單獨訪問每個項目。

如果不存在匹配結果,則可以使用SingleOrDefault返回null值或所用類型的默認值。

queryUserResponseData是XElement還是XDocument? 如果是XDocument,則需要首先訪問XML的根目錄,例如:

var userData = queryUserResponseData.Root.Elements("user")
                 .Single(u => u.Element("username").Value == userName);

除此之外,在樣本中搜索User1或User2也行。 但是,如果您搜索不存在的User3 ,Single將拋出異常。 在這種情況下,您應該使用SingleOrDefault:

var userData = queryUserResponseData.Elements("user")
                 .SingleOrDefault(u => u.Element("username").Value == "User3");

根據您對Ahmad的回答的評論,我假設當元素沒有節點時你會得到NullReferenceException。 你可以像這樣解決它 -

var userData =
    doc.Elements("user")
    .Single(u => u.Element("username") != null && u.Element("username").Value == userName);

但是如果DTD或XSD需要用戶名節點,或者您確定所有元素都有用戶名節點,則可以忽略ReSharper警告。

var userData = queryUserResponseData.Elements("user")
    .Select(u => u.Element("username"))
    .Where(uNode => uNode != null)
    .Single(uName => uName.Value == userName);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM