0

I have an IEnumerable<XElement> object that I want to query based on a certain node value, but continually get a null element error. How do I select the value of two elements based on the value of a searched element? I am attempting to return firstName and lastName where ID == somevalue.

Here is the structure of my XML:

<Profile>
    <ID>123</ID>
    <firstName>Not</firstName>
    <lastName>Registered</lastName>
</Profile>

Snippet of my query:

XDocument xdoc = XDocument.Load(someXml);
IEnumerable<XElement> nodes = xdoc.Root.Elements();
XNamespace ns = "xmlNamespace";

var name = nodes.Elements(ns + "firstName")
     .Where(x => (int)x.Element(ns + "ID") == 123)
     .SingleOrDefault();

I was basing my query on this article, but I still can't find a mixture that returns what I want.

UPDATE

I have tried the suggested answers below and still see no results or receive an Object reference not set to an instance of an object exception.

I am still working through the issue and am now trying this:

var result = xdoc
    .Descendants(ns + "Profile")
    .Where(x => (int)x.Element(ns + "ID") == 1)
    .Select(x => new { FirstName = (string)x.Element(ns + "firstName"), LastName = (string)x.Element(ns + "lastName") })
    .FirstOrDefault();

When stepping through this, the query hangs after running the Where clause.

Community
  • 1
  • 1
KidBatman
  • 585
  • 1
  • 13
  • 27

3 Answers3

1

I suppose "Profile" is not a root of your XML after all.

So if I am reading your mind correctly you have something like this:

Xml:

<root>
<Profile>
    <ID>123</ID>
    <firstName>Not</firstName>
    <lastName>Registered</lastName>
</Profile>
<Profile>
    <ID>124</ID>
    <firstName>A</firstName>
    <lastName>B</lastName>
</Profile>
</root>

Code to get profile section where id element equals to 123:

var result = XDocument.Parse(yourXml)
        .Root
        .Elements()
        .SingleOrDefault(i => i.Element("ID").Value == "123");
  • I received an `Object reference not set to an instance of an object.` exception when executing line `i.Element("ID").Value == "1"`. Please note that `ID = 1` does exist in my XML schema. – KidBatman Jul 06 '15 at 16:29
  • I posted completely working code. But you have to adjust it for your needs, since you didn't share your xml schema and check the answer from hungndv if your xml has namespace defined. – Sergey Baranchenkov Jul 07 '15 at 23:02
0

I do this examples to deal with namespace:

Profiles.xml:

<Profiles xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
    <Profile>
        <ID>122</ID>
        <firstName>Not</firstName>
        <lastName>Registered</lastName>
    </Profile>
    <Profile>   
        <ID>123</ID>
        <firstName>Not</firstName>
        <lastName>Registered</lastName>
    </Profile>
</Profiles>

Code:

XElement xDoc = XElement.Load(@"C:\Profiles.xml");
XNamespace ns = "http://schemas.microsoft.com/2004/06/E2ETraceEvent";

var profile = xDoc.Elements(ns + "Profile")
            .SingleOrDefault(x => x.Element(ns + "ID").Value == "123");
Console.WriteLine("firstName: " + profile.Element(ns + "firstName").Value);
Console.WriteLine("lastName: " + profile.Element(ns + "lastName").Value);

Hope this help.

hungndv
  • 2,121
  • 2
  • 19
  • 20
0

Your xml Like this

<?xml version="1.0" encoding="utf-8" ?>
<Employee>
  <Profile>
    <ID>123</ID>
    <firstName>Kumod</firstName>
    <lastName>Singh</lastName>
  </Profile>
  <Profile>
    <ID>124</ID>
    <firstName>Ravi</firstName>
    <lastName>Ranjam</lastName>
  </Profile>
</Employee>

We can access the first Name and Last Name

 string strPath1 = Server.MapPath("~/XmlData/abc.xml");
        var ResultOfFirLasName = (from studentProfile in XDocument.Load(strPath1).Descendants("Profile")
                                  where (int)studentProfile.Element("ID") == 123
                                  select new { FirstName = (string)studentProfile.Element("firstName"), LastName = (string)studentProfile.Element("lastName") }).FirstOrDefault();
        string strFirstName = ResultOfFirLasName.FirstName;
        string LastName = ResultOfFirLasName.LastName;

You can do with lemda expression too

var ResultOfFirLasName1 = XDocument.Load(strPath1).Descendants("Profile").Where(x => (int)x.Element("ID") == 123).Select(x=> new {FirstName =(string)x.Element("firstName"),LastName =(string)x.Element("lastName")}).FirstOrDefault();

Same way you again access the first Name and Last Name

Kumod Singh
  • 2,113
  • 1
  • 16
  • 18