2012-10-08 16 views
8

Próbuję zaimportować plik ziemi Google Earth kml do aplikacji, ale wydaje mi się, że nie można uzyskać prawidłowej składni xDocument, aby zrobić to, co chcę, jestem zastanawiasz się, czy ktoś może zaproponować sposób, aby przeczytać w pliku XML kml.Czytanie w plikach XML/KML przy użyciu C#

Rozumiem podstawy importowania xml, ale nie mogę nic zrobić z XDocument i Linq, najlepiej chciałbym, aby każde Oznaczenie miejsca było obiektem i dodać je do bazy danych opartej na Entity Framework. Wszelkie sugestie dotyczące tego, jak powinienem to zrobić, byłyby świetne, ponieważ dopiero zaczynam od Linq i mogę zrobić kilka wskazówek. XML jest określone jak poniżej

<?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> 
+0

Nie masz kodu, proszę nie zapomnij podać kodu następnym razem. – Guvante

Odpowiedz

7

Nie zawierałeś żadnego kodu, ale przypuszczam, że zapomniałeś uwzględnić swoją przestrzeń nazw podczas odniesienia do rzeczy. Oto przykład.

Podstawowe dostęp:

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

Korzystanie z przestrzeni nazw:

var ns = XNamespace.Get("http://earth.google.com/kml/2.2"); 
var placemarks = xdoc.Element(ns + "kml").Element(ns + "Document").Elements(ns + "Placemark"); 
+0

Jakiś powód użycia metody "Get", a nie niejawnej konwersji? –

+0

@ JonSkeet: Zawsze zapominam o niejawnej konwersji od czasu, gdy po raz pierwszy pracowałem z Linq do XML w F #. Większość mojego kodu używa identycznych przestrzeni nazw, więc kopiuję wokół definicji. – Guvante

5

My odgadnięcia że zapomniałeś używać nazw w LINQ do zapytań XML. To proste wystarczy wyodrębnić dane z tego:

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 
         }); 

Jeśli to nie pomoże, proszę pisać kompletny przykład, czego próbowałem, a co poszło źle.

2
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(); 
3

użyłem SharmpKml i jego documentation wydobyć informacje z pliku KML.

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; 
    } 
    } 
} 
Powiązane problemy