2012-10-08 94 views
8

Estoy tratando de importar el archivo kml xml de Google Earth a una aplicación, pero parece que no puedo obtener la sintaxis xDocument correcta para hacer lo que quiero, estoy preguntándose si alguien podría sugerir una forma de leer en el archivo kml xml.Lectura en archivos XML/KML con C#

Entiendo los conceptos básicos de la importación de xml pero no puedo conseguir nada que funcione con xDocument y Linq, idealmente me gustaría obtener cada marca de posición como un objeto y agregarlos a mi Entity Framework impulsado db. Cualquier sugerencia sobre cómo debería hacer esto sería genial, ya que estoy comenzando con Linq y podría hacerlo con algunos consejos. El XML se presenta de la siguiente manera

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

No tiene código, no olvide incluir el código la próxima vez. – Guvante

Respuesta

7

No incluyó ningún código, pero supongo que olvidó incluir su espacio de nombres al hacer referencia a cosas. Aquí hay un ejemplo.

Acceso básico:

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

Usar espacios de nombres:

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

¿Alguna razón para usar el método 'Get' en lugar de la conversión implícita? –

+0

@JonSkeet: siempre me olvido de la conversión implícita desde que trabajé con Linq en XML en F #. La mayor parte de mi código usa espacios de nombres idénticos, así que copio las definiciones. – Guvante

5

Mi suposición es que se ha olvidado de utilizar el espacio de nombres en su LINQ a las consultas XML. Es bastante fácil para extraer los datos de esta:

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

Si eso no ayuda, por favor enviar un ejemplo completo de lo que ha intentado, y lo que salió mal.

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

Solía ​​SharmpKml y su documentation para extraer información de archivo 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; 
    } 
    } 
}