Question

Je suis un novice LINQ to XML, et un novice KML également; alors sois indulgent avec moi.

Mon objectif est d’extraire des repères individuels à partir d’un fichier KML. Mon KML commence ainsi:

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

C’est ce que j’ai eu:

    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

Jusqu'à présent, rien de bon - Kml.Descendants (& "; Placemark &";) me donne une énumération vide. Le document est chargé correctement, car KML.Descendants contient tous les nœuds. Pour ce que cela vaut, ces requêtes sont également vides:

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

Quelqu'un peut-il me diriger dans la bonne direction? Des points bonus pour les liens vers de bons tutoriels Linq to XML - ceux que j'ai trouvés en ligne s'arrêtent à des scénarios très simples.

Était-ce utile?

La solution 2

Merci à spoon16 et à Bruce Murdock de m'avoir orienté dans la bonne direction. Le code que spoon16 a publié fonctionne, mais vous oblige à concaténer l’espace de nommage avec le nom de chaque élément, ce qui n’est pas aussi propre que je le souhaiterais.

J'ai fait un peu plus de recherches et j'ai compris comment cela est supposé être fait - c'est très concis et j'adore le nouveau < ... > syntaxe crochet pour faire référence aux éléments 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

Notez le : g qui suit les xmlns de la première ligne. Cela vous donne un raccourci pour faire référence à cet espace de noms ailleurs.

Pour plus d'informations sur la classe XNamespace, consultez la . Documentation MSDN .

Autres conseils

Cela fonctionne pour moi en C #:

XDocument doc = XDocument.Load(@"TheFile.kml");

var q = doc.Descendants().Where(x => x.Name.LocalName == "Placemark"); 

Scott Hanselman a une solution concise pour ceux qui recherchent une solution basée sur C #.

Prise en charge de XLINQ vers XML dans VB9

De plus, utiliser XNamespace est pratique, au lieu d’ajouter une chaîne. C’est un peu plus formel.

// 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");

Aucune des solutions ci-dessus n'a été efficace. voir mes commentaires pour plus de détails. Je pense que Spoon16 et Bruce Murdock sont sur la bonne voie, car l’espace de nommage est définitivement le problème.

Après avoir cherché Google, je suis tombé sur du code sur cette page suggérant une solution de contournement: supprimez simplement l'attribut xmlns du code XML d'origine.

    ' 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 quelqu'un peut publier un code de travail qui fonctionne avec l'espace de noms au lieu de le modifier, je lui donnerai volontiers la réponse.

Vous devrez peut-être ajouter un espace de nom au nom XElement

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

ignorer les erreurs de syntaxe, je travaille en c #

Vous constaterez qu'il peut y avoir une différence entre XElement.Name et XElement.Name.LocalName/

.

Je passe habituellement foreach dans tout le XElements de la documentation, dans un premier temps, pour m'assurer que j'utilise le bon nom.

C # Voici un extrait de mon utilisation, on dirait que j'ai oublié le {}

 private string GpNamespace = 
 "{http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions}";

 var results = admldoc.Descendants(GpNamespace + 
               "presentationTable").Descendants().Select(
                p => new dcPolicyPresentation(p));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top