Robert Smith Robert Smith - 3 months ago 12
C# Question

Combining various xml elements into one collection using GML/C#/LINQ

I am attempting to read a GML file in C#. I would like to store all the returned data in one object. So far I have been able to return all the data but in 3 separate objects:

XDocument doc = XDocument.Load(fileName);
XNamespace gml = "http://www.opengis.net/gml";

// Points
var points = doc.Descendants(gml + "Point")
.Select(e => new
{
POSLIST = (string)e.Element(gml + "pos")
});

// LineString
var lineStrings = doc.Descendants(gml + "LineString")
.Select(e => new
{
POSLIST = (string)e.Element(gml + "posList")
});

// Polygon
var polygons = doc.Descendants(gml + "LinearRing")
.Select(e => new
{
POSLIST = (string)e.Element(gml + "posList")
});


I would like to instead of creating 3 separate objects, I would like to create one object as follows:

var all = doc.Descendants(gml + "Point")
doc.Descendants(gml + "LineString")
doc.Descendants(gml + "LinearRing")....


But need some help. Thanks before hand.

Sample Data:

<gml:Point>
<gml:pos>1 2 3</gml:pos>
</gml:Point>
<gml:LineString>
<gml:posList>1 2 3</gml:posList>
</gml:LineString>
<gml:LinearRing>
<gml:posList>1 2 3</gml:posList>
</gml:LinearRing>

Answer

You can use Concat:

XDocument doc = XDocument.Load(fileName);
XNamespace gml = "http://www.opengis.net/gml";
var all = doc.Descendants(gml + "Point")
             .Concat(doc.Descendants(gml + "LineString"))
             .Concat(doc.Descendants(gml + "LinearRing"));

For getting the values as the inner elements you can do something like this:

XDocument doc = XDocument.Load("data.xml");
XNamespace gml = "http://www.opengis.net/gml";
var all = doc.Descendants(gml + "Point")
             .Select(e => new { Type = e.Name, Value = (string)e.Element(gml + "pos") })
             .Concat(doc.Descendants(gml + "LineString")
                        .Select(e => new { Type = e.Name, Value = (string)e.Element(gml + "posList") }))
             .Concat(doc.Descendants(gml + "LinearRing")
                        .Select(e => new { Type = e.Name, Value = (string)e.Element(gml + "posList") }));
Comments