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