سؤال

أنا مبتدئ في 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") 

هل يستطيع احد توجيهي الي الوجهة الصحيحة؟نقاط إضافية للروابط إلى دروس Linq to XML الجيدة - تلك التي وجدتها عبر الإنترنت تتوقف عند سيناريوهات بسيطة للغاية.

هل كانت مفيدة؟

المحلول 2

شكرًا لـoon16 وBruce Murdock لتوجيهي في الاتجاه الصحيح.الكود الذي نشرته ملعقة 16 يعمل، لكنه يفرض عليك ربط مساحة الاسم مع كل اسم عنصر، وهو ليس نظيفًا كما أريد.

لقد أجريت المزيد من البحث واكتشفت كيف من المفترض أن يتم ذلك - وهذا موجز للغاية، وأنا أحب بناء جملة القوس <...> الجديد للإشارة إلى عناصر 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 في السطر الأول.يمنحك هذا اختصارًا للإشارة إلى مساحة الاسم هذه في مكان آخر.

لمزيد من المعلومات حول فئة XNamespace، راجع وثائق MSDN.

نصائح أخرى

هذا يعمل بالنسبة لي في C#:

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

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

لدى سكوت هانسيلمان حلاً موجزًا ​​لأولئك الذين يبحثون عن حل يعتمد على لغة C#.

دعم XLINQ إلى XML في VB9

أيضًا، يعد استخدام 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");

لم يقم أي من الإصلاحات المذكورة أعلاه بالمهمة؛انظر تعليقاتي للحصول على التفاصيل.أعتقد أن كلا منoon16 وBruce Murdock يسيران على الطريق الصحيح، نظرًا لأن مساحة الاسم هي المشكلة بالتأكيد.

بعد مزيد من البحث على Google، صادفت بعض التعليمات البرمجية هذه الصفحة الذي اقترح حلاً بديلاً:فقط قم بإزالة سمة xmlns من XML الأصلي.

    ' 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 ضد 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