Reading in XML/KML files using C#

2019-03-15 17:52发布

I'm trying to import the kml xml Google earth file into an application, but i can't seem to get the xDocument syntax right in order to do what i want, i'm wondering if anyone could suggest a way to read in the kml xml file.

I understand the basics of xml import but can't get anything working with xDocument and Linq, ideally i'd like to get each Placemark as an object and add them to my Entity Framework driven db. Any suggestions as to how i should do this would be great, as i'm just starting out with Linq and could do with some pointers. The xml is laid out as below

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
  <Document>
    <Placemark>
      <name>XXX</name>
      <description>XXX</description>
      <styleUrl>XXX</styleUrl>
      <Point>
         <coordinates>XXX</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>XXX</name>
      <description>XXX</description>
      <styleUrl>XXX</styleUrl>
      <Point>
         <coordinates>XXX</coordinates>
      </Point>
    </Placemark>
  </Document>
</kml>

4条回答
再贱就再见
2楼-- · 2019-03-15 18:26

I used SharmpKml and its documentation to extract information from KML file.

using SharpKml.Dom;
using SharpKml.Engine;
using SharpKml.Dom.GX;

TextReader reader = File.OpenText(filePath);
KmlFile file = KmlFile.Load(reader);
_kml = file.Root as Kml;

sPlaceMarks[] tempPlaceMarks = new sPlaceMarks[1000];
if (_kml != null)
{
  foreach (var placemark in _kml.Flatten().OfType<Placemark>())
  {
  tempPlaceMarks[numOfPlaceMarks].Name = placemark.Name;
  tempPlaceMarks[numOfPlaceMarks].Description = placemark.Description.Text;
  tempPlaceMarks[numOfPlaceMarks].StyleUrl = placemark.StyleUrl;
  tempPlaceMarks[numOfPlaceMarks].point = placemark.Geometry as SharpKml.Dom.Point;
  tempPlaceMarks[numOfPlaceMarks].CoordinateX = tempPlaceMarks[numOfPlaceMarks].point.Coordinate.Longitude;
  tempPlaceMarks[numOfPlaceMarks].CoordinateY = tempPlaceMarks[numOfPlaceMarks].point.Coordinate.Latitude;
  tempPlaceMarks[numOfPlaceMarks].CoordinateZ = tempPlaceMarks[numOfPlaceMarks].point.Coordinate.Altitude;
  numOfPlaceMarks++;
  }

  foreach (var lookAt in _kml.Flatten().OfType<LookAt>())
  {
  Placemark placemark = (Placemark)lookAt.Parent;
  for (int i = 0; i < numOfPlaceMarks; i++)
  {
    if (placemark.Name == tempPlaceMarks[i].Name)
    {
      tempPlaceMarks[i].Name = placemark.Name;
      tempPlaceMarks[i].Description = placemark.Description.Text;
      tempPlaceMarks[i].StyleUrl = placemark.StyleUrl;
      tempPlaceMarks[i].altitude = lookAt.Altitude;
      tempPlaceMarks[i].AltitudeMode =(SharpKml.Dom.GX.AltitudeMode)lookAt.GXAltitudeMode;
      tempPlaceMarks[i].Heading = lookAt.Heading;
      tempPlaceMarks[i].Latitude = lookAt.Latitude;
      tempPlaceMarks[i].Longitude = lookAt.Longitude;
      tempPlaceMarks[i].Range = lookAt.Range;
      tempPlaceMarks[i].Tilt = lookAt.Tilt;
      break;
    }
  }
}
查看更多
Fickle 薄情
3楼-- · 2019-03-15 18:30
var xDoc = XDocument.Load("a.xml");
XNamespace ns = "http://earth.google.com/kml/2.2";

var placemarks = xDoc.Descendants(ns+"Placemark")
                    .Select(p => new
                    {
                        Name = p.Element(ns+"name").Value,
                        Desc = p.Element(ns+"description").Value
                    })
                    .ToList();
查看更多
forever°为你锁心
4楼-- · 2019-03-15 18:33

You didn't include any code, but I would guess that you forgot to include your namespace when referencing things. Here is an example.

Basic access:

var placemarks = xdoc.Element("kml").Element("Document").Elements("Placemark");

Using namespaces:

var ns = XNamespace.Get("http://earth.google.com/kml/2.2");
var placemarks = xdoc.Element(ns + "kml").Element(ns + "Document").Elements(ns + "Placemark");
查看更多
Summer. ? 凉城
5楼-- · 2019-03-15 18:42

My guess is that you've forgotten to use the namespace in your LINQ to XML queries. It's easy enough to extract the data from this:

XNamespace ns = "http://earth.google.com/kml/2.2";
var doc = XDocument.Load("file.xml");
var query = doc.Root
               .Element(ns + "Document")
               .Elements(ns + "Placemark")
               .Select(x => new PlaceMark // I assume you've already got this
                       {
                           Name = x.Element(ns + "name").Value,
                           Description = x.Element(ns + "description").Value,
                           // etc
                       });

If that doesn't help, please post a complete example of what you've tried, and what went wrong.

查看更多
登录 后发表回答