문제

저는 LINQ에서 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 ( "Placemark")는 빈 열거를 제공합니다. kml.descendants에는 모든 노드가 포함되어 있기 때문에 문서는 올바르게로드됩니다. 이 쿼리가 비어 있습니다.

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

누군가 나를 올바른 방향으로 가리킬 수 있습니까? Good LINQ ~ XML 튜토리얼 링크에 대한 보너스 포인트 - 온라인에서 찾은 튜토리얼은 매우 간단한 시나리오에서 중지됩니다.

도움이 되었습니까?

해결책 2

Spoon16과 Bruce Murdock에게 감사합니다. Spoon16이 게시 한 코드는 작동하지만 모든 단일 요소 이름으로 네임 스페이스를 연결하도록 강요합니다.

나는 조금 더 검색을 수행했고 이것이 어떻게 해야하는지 알아 냈습니다. 이것은 매우 간결하며 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

참고 :g 첫 번째 줄에서 XMLN을 따릅니다. 이것은 당신에게 다른 곳 에서이 네임 스페이스를 참조 할 수있는 바로 가기를 제공합니다.

xnamespace 클래스에 대한 자세한 내용은 MSDN 문서.

다른 팁

이것은 C#에서 나를 위해 작동합니다 :

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

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

Scott Hanselman에는 C# 기반 솔루션을 찾는 사람들을위한 간결한 솔루션이 있습니다.

VB9에서 XlinQ에서 XML 지원

또한 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));
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top