How to create a polymorphic array with linq to xml?

xelement c# create xml
c# create xml document programmatically
how to create xml file in c# with example
linq create xml
how to create xml file in c# dynamically
create xml string in c#
linq xml parsing
working with xml and linq to xml

Is it possible to use LINQ to XML to create an array of a polymorphic type?

I have 3 classes, Base, Der1 and Der2. Base is base class for Der1 and Der2. I have an xml file in which I have nodes corresponding to Der1 and Der2 objets. What I'd like to do is to parse the file and fill in a List with Der1 and Der2 objects.

xml would look like this:

<nodes>
    <node type = "Der1" attr1="val1" />
    <node type = "Der2" attr2="val2" />
</nodes>

What I tried to do but what does not work is:

List<Base> PMList = 
(from der1node from xmlDoc.Descendants("nodes") 
where der1node.type == ("Der1") 
select new Der1()
{
    Attr1 = der1node.Attribute("attr1").Value
}
).Union<Base>
(from der2node from xmlDoc.Descendants("baseNode") 
where der2node.type == ("Der2") 
select new Der2()
{
    Attr2 = der2node.Attribute("attr2").Value
}
).ToList<Base>();

Here what I tried to do is to construct Der1 objects with type=Der1 and Der2 objects with type=Der2 and add them together into a List using Union.

However this does not work. How can I get objects of different type using LINQ to XML and put them in one polymorphic collection?

One way would be to cast the new instances to their base class before projecting them:

List<Base> PMList = (from baseNode from xmlDoc.Descendants("nodes") 
                     where baseNode.type == ("Der1") 
                     select (Base) new Der1() {
                         Attr1 = baseNode.Attribute("attr1").Value
                     }
                    ).Union(
                     from baseNode from xmlDoc.Descendants("baseNode") 
                     where baseNode.type == ("Der2") 
                     select (Base) new Der2() {
                         Attr2 = baseNode.Attribute("attr2").Value
                     }
                    ).ToList();

Microsoft Visual Basic 2013 Step by Step: Micr Visu Basi 2013 St_p1, Innovative. data. management. with. LINQ. 435. LINQ tools and techniques . .​435 Fundamental query syntax. 481 Experimenting with polymorphism . Another advantage of LINQ to XML is the ability to use query results as parameters to XElement and XAttribute object constructors enables a powerful approach to creating XML trees. This approach, called functional construction, enables developers to easily transform XML trees from one shape to another.

Cast the object form select to Base type:

(from der1node from xmlDoc.Descendants("nodes") 
where der1node.type == ("Der1") 
select new Der1()
{
    Attr1 = der1node.Attribute("attr1").Value
} as Base
)

C# 2012 for Programmers, A clear, example-driven presentation of classes, objects, inheritance, polymorphism and interfaces. • Case study: Using the UML to develop an object-​oriented design and C# We use LINQ to query files, databases, XML and collections. For new objects, you can use object initializer syntax (similar to array initializer  The XElement class ends up creating an XML element or node. Line 2 uses LINQ to Objects to loop through the cars List. Notice that the select in Line 3 doesn’t just do a “select car” but creates it’s own object (namely an XElement (“Auto”…)) for each of the cars in the list. In LINQ this is known as a projection.

When you create your sequences, just make sure you cast the projection to the base type that way it becomes an IEnumerable<Base> instead of IEnumerable<Der1>.

List<Base> PMList = 
    (from der1node from xmlDoc.Descendants("nodes") 
     where der1node.type == ("Der1") 
     select new Der1()
     {
         Attr1 = der1node.Attribute("attr1").Value
     } as Base).Union(
    (from der2node from xmlDoc.Descendants("baseNode") 
     where der2node.type == ("Der2") 
     select new Der2()
     {
         Attr2 = der2node.Attribute("attr2").Value
     } as Base)).ToList();

Alternatively you can call the Cast<Base>() on the sequence beforehand.

List<Base> PMList = 
    (from der1node from xmlDoc.Descendants("nodes") 
     where der1node.type == ("Der1") 
     select new Der1()
     {
         Attr1 = der1node.Attribute("attr1").Value
     }).Cast<Base>().Union(
    (from der2node from xmlDoc.Descendants("baseNode") 
     where der2node.type == ("Der2") 
     select new Der2()
     {
         Attr2 = der2node.Attribute("attr2").Value
     }).Cast<Base>()).ToList();

LINQ to XML, XDocument xdocument = XDocument.Load("Employees.xml"); IEnumerable<​XElement> employees = xdocument.Root.Elements(); foreach (var employee in  For information about using the results of LINQ queries as the content for an XElement, see Functional Construction (LINQ to XML) (C#). Constructing elements The signatures of the XElement and XAttribute constructors let you pass the contents of the element or attribute as arguments to the constructor.

On a side note, did you consider using Concat instead of union? Union will remove duplicates, which in your current state shouldn't be issue. However, if at some point you override equality of Der1 and Der2 some items might suddenly stop appearing in the list. It's good to be aware of that.

Anyways, here's how I would do it:

var items = xmlDoc.Descendants("nodes")
    .Where(d1 => d1.type == ("Der1"))
    .Cast<Base>()
    .Concat(xmlDoc.Descendants("nodes")
        .Where(d2 => d2.type = ("Der2"))
        .Cast<Base>()
    ).ToList();

Creating XML Trees in C# (LINQ to XML), Creating XML trees in C# (LINQ to XML). 08/31/2018; 4 minutes to read. +4. In this article. Constructing elements; XElement constructors; See also. This section​  You can use LINQ to XML to perform LINQ queries over XML that you retrieve from the file system, from a remote web service, or from an in-memory XML content. This tip will only focus on querying XML using LINQ from an XML file - the Customers.xml file.

I know this comes like 7 years later. But in case the order of the elements is relevant to your use case. Here I provide an alternative without using Union that preserves the order. The following code assumes that "nodes" is the root element.

// Explicitly specify the return value to the Base type
var nodes = xmlDoc.Root.Elements().Select<XElement, Base>((e, index) => {
    string type = (e.Attribute("type") != null)?e.Attribute("type").Value:null;
    if(type != null) {
        if(type.Equals("Der1")) {
            // If you have something like an order property, you can assign it to index
            return new Der1() { Attr1 =  e.Attribute("attr1").Value };
        }
        else if(type.Equals("Der2")) {
            return new Der2() { Attr2 =  e.Attribute("attr2").Value };
        }
        else {
            return null;
        }
    } else {
        // You can also throw an Exception and handle it.
        return null;
    }
}).ToList();

Arrays, For example, creating an array of 10 integers: int[] arr = new int[10];. Indices in C# are zero-based. The indices of the array above will be 0-9. For example:. Creating xml file with linq. Today XML is generally used to store data and transport it on the web. In this post, you learn how to create an Xml file by using Linq. In the example code below, data source is a collection of few books stored in an array called Book. This data source will be used to create an XML file.

C# Language, All arrays implement the non-generic IList interface (and hence non-generic ICollection and IEnumerable base interfaces). More importantly, one-dimensional​  Examples. The following example creates a source XML tree, and then creates an XStreamingElement from a query on the source XML tree. It then serializes the XStreamingElement to the console, adds a new element to the source XML tree, and then serializes the XStreamingElement again.

C# Language, As we know we can declare an array with default values: int[] arr = new int[10];. This will create an array of 10 integers with each element of the array having value  This topic compares the XPath child elements axis to the LINQ to XML Elements axis. The XPath expression is: ./* Example. This example finds all of the child elements of the Address element. This example uses the following XML document: Sample XML File: Multiple Purchase Orders (LINQ to XML).

C# Language - Linq to Objects, LINQ queries do not execute immediately. When you are building the query you are simply storing the query for future execution. Only when you actually request​  LINQ with ArrayList. ArrayList is the part of System.Collections namespace and it allows to dynamically create array. You don't need to specify array size unlike traditional array and the size grows as you will add more element into it. However, it is slower than Array but it is more useful when you work with collection.