التعامل مع ملفات XML في الفيجوال ستوديو

مقدمة:

 

للتعامل مع ملفات الـ XML في الفيجوال ستوديو نحتاج إلى المكتبة System.XML ,, لذلك في البداية نحتاج إلى تضمين هذه المكتبة:

using System.Xml;

Imports System.Xml

 

تحوي المكتبة System.XML على الكائن XmlDocument الذي يساعدنا على فتح ملف XML وقراءة محتوياته او تعديل محتوياته.

 

ايضاً سنحتاج إلى الكائن XmlElement الذي يمثل عنصر رئيسي او عنصر جذر في ملف الـ XML ,, وايضاً الكائن XMLNode والذي يمثل عنصر فرعي في المستند.

 

بداية الشرح:

 

أولاً ,, سيكون لدينا برنامج صغير يقوم بعمليات: الإضافة – الحذف – التعديل على ملف XML , البرنامج يقوم بإنشاء ملف XML لتخزين بيانات شركات ,, بنيته هي كالتالي:

 

<Companies>

    <Company>

        <Name>Arab Developers</Name>

        <Location>

            <Country>Syria</Country>

            <City>Damascus</City>

        </Location>

        <Telephone IsMobile='no'>+963-555-1212</Telephone>

    </Company>

</Companies>

 

كما نرى ان هذا المستند يحوي سجل واحد لشركة, حيث ان العنصر الجذر في هذا المستند هو العنصر Companies اما العنصر Company فهو العنصر الذي يمثل سجل الشركة في هذا المستند اي ان كل سجل لشركة جديدة سيكون اسمه Company.

                    

بيانات الشركة هي: الاسم – الموقع (الدولة – المدينة) – الهاتف (مع خاصية هل الهاتف موبايل).

ملاحظة: لفهم هذا الدرس يجب ان يكون لديك خلفية جيدة حول ملفات XML أو قراءة الدرس: مقدمة في XML.

 

مفهوم العنصر و العقدة Element & Node:

 

كما رأينا في الدرس السابق ان مستند XML يتألف من مجموعة من المؤثرات  او التاجات Tags والتي يطلق عليها اسم "عناصر" , ومثال على ذلك <Company> … </Company>  و <City> … </City> و <Name> … </Name> إلخ ...

ولكن في الدوت نت يطلق على العنصر اسمين (XmlElement, XmlNode) اي عنصر او عقدة ...

ومن خلال تجربتي فالمفهومين متشابهين ولا فرق في استخدام اي منهما وحتى لو كان لدينا كائن من نوع XmlElement فببساطة يمكننا تحويله إلى نوع XmlNode ولن يؤثر هذه التحويل على العمل البرمجي ابداً  ولذلك اردت التنويه فقط إلى انني سأستخدم كلا المفهومين بالشرح كي تعلم عزيزي القارئ انه لافرق بينهما سواء قلت عقدة أو عنصر.

 

شرح عملية قراءة ملف الـ XML وعرض محتوياته في أداة DataGridView :

  • اولاً إنشاء نسخة من الكائن XmlDocument:

 

XmlDocument doc = new XmlDocument();

Dim doc As New XmlDocument()

  • فتح الملف بواسطة الإجراء Load والذي يقوم بفتح ملف XML عن طريق تمرير مسار الملف:

 

doc.Load(Application.StartupPath + @"\testXML.xml");

doc.Load(Application.StartupPath & "\testXML.xml")

    • توجد طريقة أخرى لقراءة ملف XML وهي XmlReader واستخدام هذا الكلاس يختلف عن استخدام XmlDocument لأن XmlReader يقوم بقراءة الملف عنصر عنصر وهكذا حتى نهاية المستند اي يقرأ بطريقة تسلسلية Sequently عكس الكلاس XmlDocument الذي يقوم بقراءة المستند كاملاً إلى الذاكرة.
    • ولذلك استخدام اي من الكلاسين يعود للمبرمج حسب احتياجاته فكل طريقة لها مميزات وسلبيات.

  • الخطوة التالية هي إنشاء نسخة من الكائن XMLElement لكي نقوم بجلب العنصر الجذر في الملف ,, لمعرفة العنصر الجذر نستخدم التابع DocumentElement:

XmlElement RootElement = doc.DocumentElement;

Dim RootElement As XmlElement = doc.DocumentElement

  • بعد معرفة العنصر الجذر سنقوم بقراءة العناصر الفرعية عنه والتي ستكون كما في مثالنا العنصر <Company> والذي هو يمثل Record اي سجل في الملف و يحوي بداخله بيانات هذا السجل.
    • لذلك يتوجب علينا اولاً عمل حلقة foreach للدوران على العناصر او السجلات الموجودة في الملف:

foreach (XmlNode child in RootElement.ChildNodes)

For Each child As XmlNode In RootElement.ChildNodes

  • الان لتسهيل العمل سنقوم بإنشاء نسخة من الكائن XmlNode والذي يمثل عقدة أو عنصر فرعي ضمن عنصر رئيسي <Company> لان العنصر <Company> هو يمثل رأس السجل في الملف ,, اذاً نقوم بعمل نسخة من الكائن لكل معلومة على حدى من المعلومات المتعلقة بالشركة.

XmlNode NameNode = child.ChildNodes[0];

XmlNode LocationNode = child.ChildNodes[1];

XmlNode PhoneNode = child.ChildNodes[2];

Dim NameNode As XmlNode = child.ChildNodes(0)

Dim LocationNode As XmlNode = child.ChildNodes(1)

Dim PhoneNode As XmlNode = child.ChildNodes(2)

  • طبعاً يجب تمرير رقم ترتيب العنصر للخاصية ChildNodes التي ترجع مصفوفة XmlNodeList تضم العناصر الفرعية التي يمثل كل منها معلومة مثل  Nameأو Location (طبعاً حسب ترتيبها في الملف كما هو واضح في الكود) , أهم شيء فهم هرمية الملف كي تستطيع استخراج المعلومة الصحيحة فالملف كله عبارة عناصر فرعية (أو أبناء) وعناصر فرعية (أبناء) تابعة لها.

 

شرح تكوين وهرمية ملف XML
  • الأن لقراءة خاصية Attribute ضمن العنصر نستخدم في الكود الخاصية  Attributes التي ترجع مصفوفة بالخصائص الموجودة ضمن العنصر ,, لقراءة الخاصية المطلوبة نمرر رقم الخاصية او اسمها كما هو بالملف , في مثالنا الخاصية IsMobile موجودة ضمن العنصر Phone :

 

bool isMobile = (PhoneNode.Attributes["IsMobile"].Value == "no" ? false : true);

Dim isMobile As Boolean = IIf(PhoneNode.Attributes("IsMobile").Value.ToLower() = "no", False, True)

  • أخيراً بعد تحضير كل شيء بقي إضافة المعلومات إلى الـDataGridView   ,, لمعرفة قيمة عنصر نستخدم الخاصية InnerText:

dataGridView1.Rows[rowsCount].Cells[0].Value = NameNode.InnerText;

dataGridView1.Rows[rowsCount].Cells[1].Value = LocationNode.ChildNodes[0].InnerText;

dataGridView1.Rows[rowsCount].Cells[2].Value = LocationNode.ChildNodes[1].InnerText;

dataGridView1.Rows(rowsCount).Cells(0).Value = NameNode.InnerText

dataGridView1.Rows(rowsCount).Cells(1).Value = LocationNode.ChildNodes(0).InnerText

dataGridView1.Rows(rowsCount).Cells(2).Value = LocationNode.ChildNodes(1).InnerText

 

  • يتبع باقي الدرس في التدوينة القادمة ان شاء الله .. والسلام عليكم ورحمة الله


4 تعليقات

معليش راح اتعبك شوي اخوي عبدالله .. في اشياء ما فهمتها كيف اقدر اتواصل معك ؟

رد

أهلاً أختي ..

يمكنك طرح جميع اسئلتك هنا كي يستفيد الأخوة زوار المدونة من الاسئلة ..

ان شاء الله سأجيب على جميع أسئلتك ...

رد

في هذا السطر :
DataGridView1.Rows(rowsCount).Cells(0).Value = NameNode.InnerText

تخرج رسالة الخطأ التالية:
Index was out of range. Must be non-negative and less than the size of the collection.

رد

متى يظهر هذا الخطأ ؟؟ اي عند الضغط على اي زر ؟؟

ارجو مزيد من التوضيح حول الخطأ

رد

إرسال تعليق