Reputation: 1477
I have an XML document that looks like this
<Elements>
<Element>
<DisplayName />
<Type />
</Element>
</Elements>
I have an interface,
interface IElement
{
string DisplayName {get;}
}
and a couple of derived classes:
public class AElement: IElement
public class BElement: IElement
What I want to do is write the most efficient query to iterate through the XML and create a list of IElement
, containing AElement
or BElement
, based on the 'Type' property in the XML.
So far I have this:
IEnumerable<AElement> elements =
from xmlElement in XElement.Load(path).Elements("Element")
where xmlElement.Element("type").Value == "AElement"
select new AElement(xmlElement.Element("DisplayName").Value);
return elements.Cast<IElement>().ToList();
But this is only for AElement
. Is there a way to add BElement
in the same query, and also make it generic IEnumerable<IElement>
? Or would I have to run this query once for each derived type?
Upvotes: 1
Views: 656
Reputation: 217263
You could use the conditional operator:
IEnumerable<IElement> elements =
from xmlElement in XElement.Load(path).Elements("Element")
let type = (string)xmlElement.Element("Type")
let name = (string)xmlElement.Element("DisplayName")
select type == "AElement"
? (IElement)new AElement(name)
: (IElement)new BElement(name);
Or, using regular syntax:
IEnumerable<IElement> elements =
XElement.Load(path)
.Elements("Element")
.Select(xmlElement =>
{
var type = (string)xmlElement.Element("Type");
var name = (string)xmlElement.Element("DisplayName");
switch (type)
{
case "AElement": return (IElement)new AElement(name);
case "BElement": return (IElement)new BElement(name);
}
throw new Exception();
});
Upvotes: 6
Reputation: 80724
IEnumerable<IElement> elements =
from e in XElement.Load(path).Elements("Element")
let elType = e.Element("Type").Value
let elName = e.Element("Name").Value
where elType == "AElement" || elType == "BElement"
select
elType == "AElement"
? (IElement) new AElement( name )
: (IElement) new BElement( name );
Upvotes: 0