質問
私はLINQ to XML初心者であり、KML初心者でもあります。私と一緒に耐えてください。
私の目標は、KMLファイルから個々の目印を抽出することです。私のKMLはこうして始まります:
<?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>
...
これは私が得た限りです:
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
これまでのところ、Kml.Descendants(<!> quot; Placemark <!> quot;)は空の列挙を提供します。 KML.Descendantsにはすべてのノードが含まれているため、ドキュメントは適切にロードされます。これらのクエリの価値についても同様に空になります:
Dim foo = Kml.Descendants("Document")
Dim foo = Kml.Descendants("Folder")
誰かが私を正しい方向に向けることができますか?良いLinq to XMLチュートリアルへのリンクのボーナスポイント-私がオンラインで見つけたチュートリアルは、非常に単純なシナリオで停止します。
解決 2
私を正しい方向に向けてくれたspoon16とBruce Murdockに感謝します。 spoon16が投稿したコードは機能しますが、名前空間とすべての要素名を連結する必要があります。これは、私が望むほどきれいではありません。
もう少し検索を行い、これがどのように行われるべきかを見つけました-これは非常に簡潔で、新しい<!> lt; ... <!> gt;が大好きです。 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
最初の行のxmlnsに続く:g に注意してください。これにより、このネームスペースを他の場所で参照するためのショートカットが提供されます。
XNamespaceクラスの詳細については、を参照してください。 MSDNドキュメント。
他のヒント
これはC#で機能します:
XDocument doc = XDocument.Load(@"TheFile.kml");
var q = doc.Descendants().Where(x => x.Name.LocalName == "Placemark");
Scott Hanselmanには、C#ベースのソリューションを探している人向けの簡潔なソリューションがあります。
また、単に文字列を追加するよりも、XNamespaceを使用すると便利です。これはもう少し形式的です。
// 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");
上記の修正プログラムはどちらも仕事をしませんでした。詳細については私のコメントをご覧ください。名前空間が間違いなく問題なので、spoon16とBruce Murdockの両方が正しい軌道に乗っていると思います。
さらにグーグルで調べた後、このページでいくつかのコードに出会いました。 回避策が提案されました。元のXMLからxmlns属性を削除するだけです。
' 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
名前空間を壊すのではなく、名前空間で機能する作業コードを投稿できる人がいれば、喜んで答えます。
XElement名に名前空間を追加する必要がある場合があります
Dim ns as string = "http://earth.google.com/kml/2.0"
dim foo = Kml.Descendants(ns + "Document")
すべての構文エラーを無視し、C#で作業します
XElement.Name
vs XElement.Name.LocalName/
通常は、ドキュメント内のすべてのforeach
をXElements
してから、正しい名前を使用していることを確認するための最初のステップとします。
C# 以下は私の使用法の抜粋です。{}
を忘れたようです private string GpNamespace =
"{http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions}";
var results = admldoc.Descendants(GpNamespace +
"presentationTable").Descendants().Select(
p => new dcPolicyPresentation(p));