在特定节点后插入XElements

3
  <user Id="4/30/2015 10:16:52 AM">
    <city>Bathinda</city>
    <city>Moga</city>
    <city>Patiala</city>
    <city>Amritsar</city>
    <city>Faridkot</city>
  </user>

我想在用户节点下创建一个具有Id属性值的条目,为此我使用了以下代码:

 xmlDocument.Elements("user")
            .Where(x => (string)x.Attribute("Id") == usrCookieId)
            .FirstOrDefault()
            .AddAfterSelf(
                 new XElement("adults", drpAdult1.SelectedIndex),
                 new XElement("kids", Convert.ToInt32(drpKids.SelectedIndex)),
                 new XElement("infants", Convert.ToInt32(drpInfants.SelectedIndex)),
                 new XElement("startingDate", datePicker.Value),
                 new XElement("startingCity", drpStartingCity.SelectedValue ));

但是错误是:对象引用未设置为对象的实例。 我该如何纠正上面的代码。 谢谢!


1
也许你没有任何与输入匹配的用户?最好在这里使用First()而不是FirstOrDefault(),因为如果没有匹配的元素,你将会得到一个NullReferenceException,这比First()爆炸并表示没有匹配更不清晰。 - Jon Skeet
一个简短但完整的程序演示问题将有助于我们帮助您解决问题... - Jon Skeet
1
你可以用 FirstOrDefault 替换 Where,因为 SingleSingleOrDefaultFirstFirstOrDefault 都是在适当的时候退出的 Where - Chuck Savage
2个回答

3

您遇到对象引用异常是因为没有用户 ID 与 usrCookieId 中的值匹配。您需要检查 null 值以避免此异常,方法是首先获取该元素并确认是否存在该用户节点,然后再添加它:

XElement userNode = xdoc.Descendants("user")
                        .FirstOrDefault(x => (string)x.Attribute("Id") == usrCookieId);

如果找不到对应的用户节点,这将返回第一个匹配的XElement或null,因此您可以简单地检查此条件并相应地添加:

if (userNode != null)
{
       userNode.AddAfterSelf(new XElement("adults", "3"),
                             new XElement("kids", 2),
                             new XElement("infants", 5),
                             new XElement("startingDate", "23/01.2015"),
                             new XElement("startingCity", "Delhi"));
}

另外请注意,由于您打算将此新节点添加到 user 下面,因此您需要一个根节点,因为当前 user 充当了根节点,通过添加这些新节点,您将使 XML 不符合格式,并且它将抛出运行时异常。因此最好像这样拥有根节点:

 <Users>
  <user Id="1">
    <city>Bathinda</city>
    <city>Moga</city>
    <city>Patiala</city>
    <city>Amritsar</city>
    <city>Faridkot</city>
  </user>
</Users>

1
我没有提到,但是有一个<Users>与您指定的相同,不过还是谢谢。您提到的书真的很好,谢谢。 - Anil Sharma

1
您未找到匹配项,因此usrCookieID可能不等于任何Id,或者更有可能的是,User不是您XML的根。如果不是,也许Descendants在这里更合适-它会查找文档中的任何User元素。
如果Id是唯一的,则使用First(或Single)比FirstOrDefault更合适,因为会抛出更好的异常。这将抛出一个解释没有找到元素的异常,而不是无用的NullReferenceException
要向结果添加子元素,您需要使用AddAddAfterSelf将添加同级元素。
所以,类似如下:
var user = xmlDocument.Descendants("user")
    .Where(x => (string)x.Attribute("Id") == usrCookieID)
    .Single();

user.Add(new XElement(...));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接