Frage

Ich bin ein LINQ to XML-Neuling, und eine KML-Neuling als auch, haben Sie etwas Geduld.

Mein Ziel ist, einzelne Ortsmarken aus einer KML-Datei zu extrahieren. Meine KML beginnt so:

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

Das ist so weit ich habe bekommen:

    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

Bisher kein guter - Kml.Descendants ( „Place“) gibt mir eine leere Aufzählung. Das Dokument wird richtig geladen - weil KML.Descendants jeden Knoten enthält. Für das, was es wert ist kommen diese Abfragen leer als auch nach oben:

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

Kann mir jemand in die richtige Richtung? Bonuspunkte für Links zu gutem Linq to XML-Tutorials - diejenigen, habe ich Online-Stopp bei sehr einfachen Szenarien gefunden.

War es hilfreich?

Lösung 2

Dank spoon16 und Bruce Murdock für mich in der richtigen Richtung. Der Code, der spoon16 Werke geschrieben, sondern zwingt Sie den Namespace mit jedem einzelnen Elementnamen verketten, die nicht so sauber ist, wie Ich mag würde.

Ich habe ein bisschen mehr Suche gemacht und ich habe herausgefunden, wie das soll getan werden - das Super prägnant ist, und ich liebe die neue <...> Klammer-Syntax für XML-Elemente zu beziehen

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

Beachten Sie die : g im Anschluss an die xmlns in der ersten Zeile. Dies gibt Ihnen eine Verknüpfung an anderer Stelle auf diesen Namespace zu verweisen.

Für mehr über die XNamespace Klasse finden Sie in der MSDN-Dokumentation .

Andere Tipps

Dies funktioniert für mich in C #:

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

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

Scott Hanselman hat eine kurze Lösung für diejenigen, die eine C # basierte Lösung suchen.

XLinq zu XML-Unterstützung in VB9

Auch XNamespace Verwendung ist praktisch, anstatt nur einen String anhängt. Das ist ein bisschen mehr 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");

Keine der oben genannten Korrekturen hat den Job; siehe meine Kommentare für weitere Einzelheiten. Ich glaube, beide spoon16 und Bruce Murdock ist auf dem richtigen Weg, da der Namespace auf jeden Fall das Problem.

Nach weiteren Googeln ich über einige Code kam auf dieser Seite dass vorgeschlagen eine Abhilfe: nur die xmlns aus der ursprünglichen XML-Attribute Streifen

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

Wenn jemand schreiben kann Code arbeiten, die mit dem Namensraum arbeitet, anstatt es zu nuking, ich werde sie gerne die Antwort geben.

Sie müssen möglicherweise einen Namespace auf den XElement Namen hinzuzufügen

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

ignorieren Syntaxfehler, die ich in c # arbeiten

Sie finden es kann ein Unterschied in dem XElement.Name vs XElement.Name.LocalName/ sein

ich in der Regel foreach durch alle XElements im doc als ein erster Schritt, um sicherzustellen, dass ich die richtige Namensgebung bin mit.

C # Hier ein Auszug meiner Nutzung, sieht aus wie ich die {}

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

 var results = admldoc.Descendants(GpNamespace + 
               "presentationTable").Descendants().Select(
                p => new dcPolicyPresentation(p));
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top