Reputation: 17669
Below is the sample XML that I am trying to read using Linq to XML:
<root>
<Employee>
<Name>Jeff</Name>
<Department>Account</Department>
</Employee>
<Employee>
<Name>David</Name>
<Department>Finance</Department>
</Employee>
<Employee>
<Name>Neil</Name>
<Department>Sales</Department>
</Employee>
<Employee>
<Name>Jason</Name>
<Department>Retail</Department>
</Employee>
</root>
Now, I need to select Employee
elements which are from "Account" Department
. If there are none in Account
then I need to pick Employee
element from Finance
.
How can I do that?
Upvotes: 4
Views: 176
Reputation: 37299
Combining Linq and XPath you can do it like this:
var document = XDocument.Load("data.xml").Root;
//Find a Department with a given value and retrieve its Employee parent
string xPath = "//Department[text() = '{0}']/parent::Employee";
//Search for "Account" Department. If nun was found will return null and then
//search for "Finance"
var employee = document.XPathSelectElement(string.Format(xPath, "Account")) ??
document.XPathSelectElement(string.Format(xPath, "Finance"));
If you do not want to use XPath then you can do this:
var employee = (from item in XDocument.Load("data.xml").Descendants("Employee")
let department = item.Element("Department").Value
orderby department == "Account" ? 1 :
department == "Finance" ? 2 : 3
select item).FirstOrDefault();
For all employees of those departments:
var employee = (from item in XDocument.Load("data.xml").Descendants("Employee")
group item by item.Element("Department").Value into grouping
orderby grouping.Key == "Account" ? 1 :
grouping.Key == "Finance" ? 2 : 3
select grouping.ToList()).FirstOrDefault();
Upvotes: 0
Reputation: 125197
As an option you can use this code:
var result = XElement.Parse(xml).Descendants("Employee")
.GroupBy(x => x.Element("Department").Value)
.OrderByDescending(x=>x.Key=="Account")
.FirstOrDefault(x => (x.Key == "Account" && x.Count() > 0) ||
x.Key == "Finance").ToList();
Upvotes: 1
Reputation: 18127
You can do this, it is not the most elegant way. Just use ||
and take FirstOrDefault
var result = doc.Root.Descendants("Employee").
Where(x => x.Element("Department").Value == "Account" || x.Element("Department").Value == "Finance").
FirstOrDefault();
Upvotes: 0