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>

I want to make an entry in under user node having Id attribute value for this purpose I've used the code following:->

 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 ));

But the Error is Object refrence is not set to an instance of an object. How can i correct my code above. Thanks!

Chuck Savage
  • 11,775
  • 6
  • 49
  • 69
Anil Sharma
  • 55
  • 1
  • 8
  • 1
    Well maybe you haven't *got* any users matching the input? It would be better to use `First()` here rather than `FirstOrDefault()` as if there aren't any matching elements you *will* get a `NullReferenceException`, which is less clear than `First()` going bang saying there are no matches. – Jon Skeet Apr 30 '15 at 15:59
  • A short but complete program demonstrating the problem would help us to help you though... – Jon Skeet Apr 30 '15 at 15:59
  • 1
    You can replace the `Where` with the `FirstOrDefault` since `Single`, `SingleOrDefault`, `First` and `FirstOrDefault` are `Where's` that quit when appropriate. – Chuck Savage Apr 30 '15 at 16:38

2 Answers2

3

You are getting Object Reference Exception because no User Id must be matching the value present in usrCookieId. You need to check for nulls to avoid this exception by first fetching the element and adding it after confirming if that user node is present:-

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

This will return the first matching XElement or null in case no such user node is found so you can simply check this condition and add accordingly:-

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"));
}

Also, Please note since you are intending to add this new node beneath user you need to have a root node because currently user is acting as root node and by adding this new nodes you will make you XML not well formed and it will throw a run time exception So better have a Root node like this:-

 <Users>
  <user Id="1">
    <city>Bathinda</city>
    <city>Moga</city>
    <city>Patiala</city>
    <city>Amritsar</city>
    <city>Faridkot</city>
  </user>
</Users>
Rahul Singh
  • 21,585
  • 6
  • 41
  • 56
  • 1
    I didn't mention But there is same as u specified But thanks for this. and the book u referred is really good Thanks – Anil Sharma Apr 30 '15 at 17:55
1

You're not finding a match, so either usrCookieID doesn't isn't equal to any Id or, maybe more likely, User isn't the root of your XML. If it isn't, perhaps Descendants would be more appropriate here - this finds any User element in the document.

First (or Single if Id is unique) would be more appropriate than FirstOrDefault, as a better exception would be thrown. This will throw an exception explaining that no element was found rather than an unhelpful NullReferenceException.

To add a child element to your result, you need to use Add. AddAfterSelf will add a sibling element.

So, something like:

var user = xmlDocument.Descendants("user")
    .Where(x => (string)x.Attribute("Id") == usrCookieID)
    .Single();

user.Add(new XElement(...));
Charles Mager
  • 25,735
  • 2
  • 35
  • 45