Search code examples
c#xmlparsingkml

Looping through a .KML file and Finding Values in Side a Particular Node?


I have a .kml file which I am unable to parse through the SharpKml assemblies; probably the format is not compatible--certainly, there is a lot of junk in the file.

But I have found out that I can use XDocument.Load() function in a C# console application and see that loaded document. So I am planning to use standard .NET xml functions to parse the .kml file. I think I should be able to do that?

Basically, I am interested in parsing the <PlaceMark> node which exists along with the junk/un-needed data. Here is the structure of the node:

<Placemark>
    <Snippet></Snippet>
    <styleUrl>#style0</styleUrl>
    <ExtendedData>
        <SchemaData schemaUrl="#Bracket_Hall_RoomData">
            <SimpleData name="FID">0</SimpleData>
            <SimpleData name="Room">230C</SimpleData>      
        </SchemaData>
    </ExtendedData>
    <Polygon>
        <extrude>false</extrude>
        <tessellate>false</tessellate>
        <outerBoundaryIs>
            <LinearRing>
                <extrude>false</extrude>
                <tessellate>false</tessellate>
                <coordinates>-82.836315,34.678898,0.000000 -82.836317,34.678886,0.000000...</coordinates>
            </LinearRing>
        </outerBoundaryIs>
    </Polygon>
</Placemark>

Again, there will be multiple such nodes in the document. I have looked at other code samples but they are too complicated.


Solution

  • Your questions is a little vague in terms of what you're trying to do. You say you want to parse the <Placemark> node but there may be additional <Placemark> nodes among the "junk" in the file. It's unclear whether you want all the <Placemark> nodes or a specific one. So, taking a guess, once you've loaded the XML into the XDocument you can issue a LINQ-to-XML query to get all the <Placemark> nodes.

    var placemarks =
        (from x in xDoc.Descendants()
         where x.Name.LocalName == "Placemark"
         select new XElement(x)).ToList();
    

    You can now loop over the placemarks variable (which is a collection) and do what you need to with each. This is a very simple implementation, assuming there is only one fid, room, and coordinates node per placemark.

    foreach (var placemark in placemarks)
    {
        var fid = (from x in placemark.Descendants("SimpleData")
                   where x.Attribute("name").Value == "FID"
                   select x).First().Value;
        var room = (from x in placemark.Descendants("SimpleData")
                    where x.Attribute("name").Value == "Room"
                    select x).First().Value;
        var coord = (from x in placemark.Descendants("coordinates")
                     select x).First().Value;
    }