vb.net linq-to-xml kml

vb.net - Linq a XML para KML?



linq-to-xml (5)

Ninguno de los arreglos anteriores hizo el trabajo; ver mis comentarios para más detalles. Creo que tanto spoon16 como Bruce Murdock están en el camino correcto, ya que el espacio de nombres es definitivamente el problema.

Después de buscar en Google, me encontré con un código en esta página que sugería una solución: simplemente quita el atributo xmlns del XML original.

'' Read raw XML Dim RawXml As String = ReadFile("../kmlimport/ga.kml") '' HACK: Linq to XML choking on the namespace, just get rid of it RawXml = RawXml.Replace("xmlns=""http://earth.google.com/kml/2.0""", "") '' Parse XML Dim Kml As XDocument = XDocument.Parse(RawXml) '' Loop through placemarks Dim Placemarks = From Placemark In Kml.<Document>.<Folder>.Descendants("Placemark") For Each Placemark As XElement In Placemarks Dim Name As String = Placemark.<name>.Value ... Next

Si alguien puede publicar código de trabajo que funcione con el espacio de nombres en lugar de anularlo, con mucho gusto les daré la respuesta.

Soy un novato LINQ to XML y un novato KML también; así que tengan paciencia conmigo.

Mi objetivo es extraer Placemarks individuales de un archivo KML. Mi KML comienza así:

<?xml version="1.0" encoding="utf-8"?> <Document xmlns="http://earth.google.com/kml/2.0"> <name>Concessions</name> <visibility>1</visibility> <Folder> <visibility>1</visibility> <Placemark> <name>IN920211</name> <Style> <PolyStyle> <color>80000000</color> </PolyStyle> </Style> <Polygon> <altitudeMode>relativeToGround</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates>11.728374,1.976421,0 11.732967,1.965322,0 11.737225,1.953161,0 11.635858,1.940812,0 11.658102,1.976874,0 11.728374,1.976421,0 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> <Placemark> ...

Esto es todo lo que he conseguido:

Dim Kml As XDocument = XDocument.Load(Server.MapPath("../kmlimport/ga.kml")) Dim Placemarks = From Placemark In Kml.Descendants("Placemark") _ Select Name = Placemark.Element("Name").Value

Hasta ahora no es bueno - Kml.Descendants ("Placemark") me da una enumeración vacía. El documento se carga correctamente, porque KML.Descendants contiene todos los nodos. Por lo que vale, estas consultas también aparecen vacías:

Dim foo = Kml.Descendants("Document") Dim foo = Kml.Descendants("Folder")

¿Alguien me puede apuntar en la dirección correcta? Puntos de bonificación por enlaces a buenos tutoriales de Linq a XML: los que he encontrado en línea se detienen en escenarios muy simples.


Gracias a spoon16 y Bruce Murdock por señalarme en la dirección correcta. El código que publicó spoon16 funciona, pero te obliga a concatenar el espacio de nombres con cada nombre de elemento, que no es tan limpio como me gustaría.

He hecho un poco más de búsqueda y he descubierto cómo se supone que debe hacerse, esto es súper conciso, y me encanta la nueva sintaxis del paréntesis <...> para referirse a elementos XML.

Imports <xmlns:g=''http://earth.google.com/kml/2.0''> Imports System.Xml.Linq ... Dim Kml As XDocument = XDocument.Load(Server.MapPath("../kmlimport/ga.kml")) For Each Placemark As XElement In Kml.<g:Document>.<g:Folder>.<g:Placemark> Dim Name As String = Placemark.<g:name>.Value Next

Tenga en cuenta lo siguiente : g después de xmlns en la primera línea. Esto le da un atajo para referirse a este espacio de nombre en otro lugar.

Para obtener más información sobre la clase XNamespace, consulte la documentación de MSDN .


Es posible que deba agregar un espacio de nombres al nombre XElement

Dim ns as string = "http://earth.google.com/kml/2.0" dim foo = Kml.Descendants(ns + "Document")

ignorar cualquier error de sintaxis, trabajo en c #

Encontrará que puede haber una diferencia en XElement.Name vs XElement.Name.LocalName/

Por lo general, busco todos los XElements en el documento como un primer paso para asegurarme de que estoy usando el nombre correcto.

C # Aquí hay un extracto de mi uso, parece que olvidé el {}

private string GpNamespace = "{http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions}"; var results = admldoc.Descendants(GpNamespace + "presentationTable").Descendants().Select( p => new dcPolicyPresentation(p));


Esto funciona para mí en C #:

XDocument doc = XDocument.Load(@"TheFile.kml"); var q = doc.Descendants().Where(x => x.Name.LocalName == "Placemark");


Scott Hanselman tiene una solución concisa para aquellos que buscan una solución basada en C #.

Soporte de XLINQ a XML en VB9

Además, usar XNamespace es útil, en lugar de simplemente agregar una cadena. Esto es un poco más formal.

// This code should get all Placemarks from a KML file var xdoc = XDocument.Parse(kmlContent); XNamespace ns = XNamespace.Get("http://earth.google.com/kml/2.0"); var ele = xdoc.Element(ns + "kml").Element(ns + "Document").Elements(ns + "Placemark");