Reputation: 595
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.
Upvotes: 0
Views: 585
Reputation: 2163
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
Upvotes: 0
Reputation: 2141
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.
Upvotes: 0
Reputation: 624
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");
Upvotes: 1