المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : الدرس الحادي عشر : التعامل مع ملفات XML - دورة CSharp 2005


khaledbelal
03-22-2010, 04:10 PM
الدرس الحادي عشر

دوارة While

في الدرس الرابع تعرفنا على هيكل من هياكل التكرار في لغة C# وهو دوارة for

والحقيقة أن هناك هياكل أخرى من هياكل التكرار أهمها هي دوارة While

وهي تشبة إلى حد كبير دوارة for بإختلاف أنها لا تحتوي على عداد Counter كما كنا نعرف i في دوارة for

والهيكل الأساسي لدوارة While يشبة إلى حد كبير هيكل for بإختلاف أشياء بسيطة :


while (شرط التكرار)
{
كود الدوارة
}

تقوم جملة while بتكرار كود الدوارة ما دام شرط التكرار متحققاً , مثلاً :

int n=0;
while (n<5)
{
MessageBox.Show("من داخل الدوارة ");
n++;
}

الدوارة السابقة تقوم بإظهار الرسالة خمس مرات

حيث عرفنا متغير من نوع رقم n وأسندنا له قيمة إبتدائية 0

وشرط التكرار في الدوارة هو أن تكون قيمة المتغير n أصغر من 5

في المرة الأولى ستكون قيمة n هي صفر , وبالتالي فشرط التكرار متحقق , لأن الصفر أقل من 5

يتم تنفيذ كود إظهار الرسالة , والكود n++ يعني إضافة واحد إلى قيمة n أي أن n سيحمل الآن القيمة 1

يعود المعالج لبداية جملة while ويختبر شرط التكرار مرة أخرى ثم ينفذ كود إظهار الرسالة ويزيد واحد لقيمة n

وهكذا حتى تصبح قيمة n=5 عندها لن يتحقق شرط التكرار لأن 5 لسيت أقل من 5

وبالتالي يقفز المعالج إلى نهاية كود الدوارة ويواصل تنفيذ التعليمات بعدها

يستخدم هذا النوع من الدوارات حين لا نعرف كم بالضبط سنكرر كود الدوارة

وسنستخدمها في درس اليوم حيث لدينا معلومات الألبوم ولا نعرف عدد الملفات في الألبوم كما سنشرح بالتفصيل لا حقا

ملفات XML

من اهم أنظمة الحاسوب التي استفادة منها الإنسانية منذ ظهور الحاسوب هي أنظمة قواعد البيانات

وأنظمة قواعد البيانات هي برمجيات تستخدم مع لغات البرمجة بغرض خزن وإسترجاع أنواع متعددة من البيانات

ويتم خزن هذه البيانات بطرق مرتبة ومنهجية بحيث يسهل إسترجاع بيانات محددة مهما كبير كان حجم البيانات

حيث يتم ترتيب البيانات في وحدات متجانسة تسمى جداول Tables والتي تحتوي على حقول Fields لكل حقل نوع محدد من البيانات

ويمكن للجدول الواحد أن يحتوي على عدة حقول من أنواع بيانات مختلفة

قد ترتبط الجداول مع بعضها بواسطة علاقات Relationships حيث تعتمد بيانات من جدول على بيانات من جدول آخر

أنظمة قواعد البيانات تقسم إلى قسمين , نظام الخزن , ونظام المعالجة

أما نظام الخزن فهو المسئول عن خزن البيانات في ملفاتها المحددة بغض النظر عن ترتيبها أو أماكنها

ونظام المعالجة هو المسئول عن تحديد أماكن البيانات الصحيحة و إسترجاعها والقيام بالعمليات عليها

النظام الأول -نظام الخزن- يتكفل به نظام التشغيل ولا يحتاج لبرمجيات أو برامج خاصة

أما النظام الثاني فيتطلب برمجيات محددة لنظام قواعد البيانات

معظم أنظمة قواعد البيانات تستخدم النظام الثاني , مثل قواعد الأكسس و الأوراكل و غيرها

هناك أنواع أخرى لا تتطلب برمجيات مخصصة للتعامل معها ومنها نظام قواعد البيانات عبر ملفات XML

وهذا هو محور درسنا اليوم , حيث لا يحتاج هذا النظام لبرمجيات متخصصة للتعامل معه

وإنما ملفاته عبارة عن ملفات نصية يمكن فتحها وتعديلها بأي محرر نصوص

وسنستخدم ملفات XML في تطبيقنا لخزن بيانات الألبومات أو قوائم التشغيل

صيغة هذه الملفات النصية تشبة إلى حد كبير صيغة ملفات HTML

حيث يعتمد على وسوم Tags ترتب البيانات في هياكل مترابطة

وكل جزء من البيانات يحتوي على وسم بداية ووسم نهاية وله إسم محدد

فمثلاً هذا الكود :


<msg>رسالة</msg>

هذا جزء من كود ملف XML حيث يحتوي على جزء لخزن البيانات إسمه msg

يحتوي هذا الجزء على بيانات مخزنة هو كلمة "رسالة" لاحظ أن الجزء يحتوي على وسمين

وسم البداية حيث يحتوي على إسم الجزء بين علامتي أصغر وأكبر من

ووسم النهاية وهو مشابه تماما لوسم البداية بزيادة الشرطة المائلة / قبل إسم الجزء في وسم النهاية

وبين الوسمين توجد البيانات

وتسمى الأجزاء في ملفات XML بالعقد Nodes فالكود السابق يحتوي على عقدة إسمها msg

سميت بالعقد لأنه يمكن لأي جزء من البيانات أن يحتوي على أجزاء أخرى :


<albumes>
<albume1>

</albume1>
</albumes>

الكود السابق يحتوي على عقدة رئيسية إسمها albumes تحتوي بدورها على عقدة فرعية إسمها albume1

يمكن أن تحتوي العقدة على عدة عقد فرعية :


<albumes>

<albume1>
</albume1>

<albume2>
</albume2>

</albumes>

لعقدة الرئيسية albumes تحتوي على عقدتين فرعيتين albume1 و albume2

يمكن أيضاً للعقدة الفرعية أن تحتوي على عقد فرعية أخرى:


<albumes>

<albume1>
<file>sound.mp3</file>
<file>wave.rm</file>
</albume1>

<albume2>
<file>real.wav</file>
</albume2>

</albumes>

العقدة الرئيسية albumes تحتوي على عقدتين فرعيتين albume1 و albume2

العقدة الفرعية albume1 تحتوي على عقدتين فرعيتين بنفس الإسم file

كل عقدة من عقدتي file بيانات نصية sound.mp3 و wave.rm

والعقدة الفرعية albume2 تحتوي على عقدة فرعية file

الكود السابق يمثل ملف XML يحتوي على بيانات مرتبة في عقد , ولكن ينقصة شيئ مهم

نوع التكويد في المف , ورقم إصدار كود XML , والتكويد هو أسلوب خزن البيانات النصية في الملف

عادة ما نستخدم تكويد UTF-8 , وسطر نوع التكويد يجب أن يكون في بداية الملف:


<?xml version="1.0" encoding="utf-8"?>
<albumes>
<albume1>
<file>sound.mp3</file>
<file>wave.rm</file>
</albume1>
<albume2>
<file>real.wav</file>
</albume2>
</albumes>

هذا السطر لا يتغير في معظم ملفات XML

هذا هو هيكل الملف الذي سيقوم بخزن بيانات الألبومات وقوائم التشغيل

يتم التعامل مع ملف XML في البرنامج من خلال كائن XmlDocument الموجود في فضاء الأسماء System.XML:


XmlDocument doc = new XmlDocument();

الكود السابق عرفنا من خلالة كائن إسمه doc من نوع XmlDocument

الكائن doc يقوم بتحميل المف عن طريق الإجراء Load


doc.Load("c://albumes.xml");

الكود السابق يقوم بتحميل الملف albumes.xml الموجود في القرص c إلى الكائن doc

يتم الوصول إلى العقد الموجوده في المف عن طريق ذكر إسم العقدة الرئيسية متبوعة بقوسين مربعين يحتويان إسم العقدة الفرعية

أما إذا أردنا الوصول إلى العقد الرئيسية المسماه albumes فنكتب إسم الكائن doc متبوعاً بقوسين مربعين يحتويان إسم العقدة :


doc["albumes"];

ويتم الوصول إلى البيانات في العقدة بواسطة الخاصية InnerText :


MessageBox.Show(doc["albumes"].InnerText);

الكود السابق يقوم بإظهار رسالة تحتوي على البيانات المخزنة في العقدة albumes

ويتم الوصول لإسم العقدة عن طريق الخاصية :Name


MessageBox.Show(doc["albumes"].Name);

الكود السابق يظهر رسالة تحتوي على إسم العقدة albumes

ويتم الوصول إلى العقد الفرعية بإضافة قوسين مربعين يحتويان إسم العقدة

فمثلاً للوصول إلى العقدة الفرعية albume1 الموجود في العقدة albumes :


doc["albumes"]["albume1"]

وللوصول إلى العقدة الأعمق file :


doc["albumes"]["albume1"]["file"]

التطبيق

افتح تطبيق الدرس السابق , من نافذة مستعرض المشروع, أنقر بالزر الأيمن على إسم المشروع

ومن القائمة الناتجة إختر Add ثم New Item :


http://absba7.absba.org/teamwork8/455943/89.jpg

ستظهر نافذة إضافة ملف جديدة للمشروع , من القائمة في اليسار إختر misc

ثم إختر Empty XML file , وفي صندوق إسم الملف أكتب الإسم التالي albumes.xml , وإختر OK

http://absba7.absba.org/teamwork8/455943/90.jpg

إذهب إلى مجلد المشروع وأنسخ الملف albumes.xml إلى مجلد Debug الموجود داخل مجلد bin

حيث يصبح الملف موجود بجانب ملفات المشروع الأخرى

الآن قم بفتح تصميم نافذة الألبومات وسحب ثلاثة أزرار إلى النافذة وغير الأسماء فيها إلى

ألبوم جديد

حفظ الألبوم

حذف الألبوم

ومن صندوق الأدوات إسحب كائن القائمة المنسدلة إلى نافذة الالبومات :

http://absba7.absba.org/teamwork8/455943/91.jpg

إختر كائن القائمة المنسدلة و من جدول الخصائص , غير الخاصية (Name) , إلى ac

وغير الخاصية Text إلى "إختر الألبوم"

قم بترتيب الأدوات في النافذة حتى تصبح هكذا :

http://absba7.absba.org/teamwork8/455943/92.jpg

جميع الدوال التي سنستخدمها للتعامل مع ملف XML موجوده في فضاء الأسماء XML الموجود داخل الفضاء System

لذلك يجب إضافة عبارة using لتعريف جميع دوال وكائنات التعامل مع ملفات XML

إذهب إلى شفرة نافذة الألبومات و أكتب السطر التالي , تحت جمل using في رأس الملف:

http://absba7.absba.org/teamwork8/455943/93.jpg

يتم تحميل ملف XML إلى البرنامج والتعامل معه من خلال كائن XmlDocument

حيث سنعرف كائن عام من هذا النوع ليتم التعامل معه في جميع أنحاء نافذة الألبومات

إنسخ كود التعريف تحت تعريف قائمة albume من الدرس السابق :

http://absba7.absba.org/teamwork8/455943/94.jpg

قمنا هنا بتعريف كائن إسمه doc من نوع XmlDocument , ولأنه كائن إستخدمنا الكلمة new


إجراء تحميل الألبومات للقائمة المنسدلة FillCombo

يقوم هذا الإجراء بتحميل أسماء الألبومات الموجوده في ملف XML إلى القائمة المنسدلة ac

قم بنسخ الكود التالي إلى شفرة نافذة الألبومات وتأكد أنه خارج أي إجراء آخر :


void FillCombo()
{
doc.Load(Application.StartupPath + "//albumes.xml");
XmlNode alnd = doc["albumes"].FirstChild;
while (alnd != null)
{
ac.Items.Add(alnd.Name);
alnd = alnd.NextSibling;
}
}

السطر الأول يقوم بتحميل الملف إلى الكائن doc

والتعليمة Application.StartupPath تعيد قيمة نصية تمثل مسار ملف exe للتطبيق

حيث إستفدنا من هذه التعليمة لمعرفة مسار ملف XML وأضفنا إسم الملف للمسار

في السطر الثاني قمنا بتعريف كائن من نوع عقدة XmlNode إسمه alnd

ثم حملنا هذا الكائن أول عقدة فرعية داخل العقدة الرئيسية albumes من خلال الخاصية FirstChild

السطر الثالث يمثل جملة while تنفذ كود الدوارة ما دامت العقدة alnd تحمل قيمة

الشرط alnd!=null يختبر الكائن alnd فإذا كان يحمل قيمة غير القيمة الفارغة null فسيتم تنفيذ كود الدوارة

أما إذا كان الكائن alnd لا يحمل قيمة أي أنه يحمل null فعندها لن يتم تنفيذ كود الدوارة

السطر الخامس يقوم بإضافة إسم العقدة alnd إلى القائمة المنسدلة ac

السطر السادس يقوم بإختيار العقدة التالية للعقدة alnd حيث يحمل الكائن alnd العقد التالية لما كان يحمله

يتم تكرار السطرين السابقين حتى الوصول إلى آخر عقدة عندها سيحمل الكائن alnd القيمة null لأنه لا يوجد عقدة تالية للعقدة الأخيرة

وبالتالي ينتهي تكرار جملة while

لكن ماذا لو لم يكن هناك إي عقد في ملف XML , عندها سينتج خطأ من تنفيذ هذا الإجراء ولحل ذلك نستخدم عبارة try:

قم بتعديل الكود السابق حتى يصبح هكذا :


void FillCombo()
{
try
{
doc.Load(Application.StartupPath + "//albumes.xml");
XmlNode alnd = doc["albumes"].FirstChild;
while (alnd != null)
{
ac.Items.Add(alnd.Name);
alnd = alnd.NextSibling;
}
}
catch
{
MessageBox.Show("حدث خطأ أثناء إسترجاع بيانات الألبومات");
}
}

بعد شرح إجراء FillCombo بقي أن نحدد مكانا مناسباً لإستدعاءه , وأفضل مكان لذلك هو عند تحميل النافذة

إذا إلى تصميم نافذة الألبومات وانقر مزدوجاً على مكان فارغ في النافذة لتذهب إلى كود تحميل النافذة albumes_Load

أضف إستدعاء إجراء FillCombo تحت إجراء FillView من الدرس السابق , حيث يصبح كود تحميل النافذة هكذا :


void AlbumesLoad(object sender, System.EventArgs e)
{
FillView();
FillCombo();
}

إجراء قراءة محتويات الألبوم ReadAlbume

سيقوم هذا الإجراء بقراءة محتويات ألبوم محدد من ملف XML وتخزينها في قائمة albume

ثم إستدعاء إجراء FillView لنسخ محتويات القائمة إلى كائن المستعرض lv

يحتوي هذا الإجراء على مدخل من نوع نص يمثل الألبوم المختار المراد تحميل ملفاته إلى كائن المستعرض

إنسخ الكود التالي إلى شفرة نافذة الألبومات وتأكد أنه خارج أي إجراء آخر:


void ReadAlbume(string albumename)
{
try
{
doc.Load(Application.StartupPath + "//albumes.xml");
XmlNode filend = doc["albumes"][albumename].FirstChild;
albume.Clear();
while (filend != null)
{
albume.Add(filend.InnerText);
filend = filend.NextSibling;
}
FillView();
}
catch
{
MessageBox.Show("حدث خطأ أثناء محاولة إسترجاع بيانات الألبومات");
}
}

السطر الأول من الكود يحتوي على إسم الإجراء وإسم المدخل ونوعة string

السطر الخامس لتحميل ملف XML إلى الكائن doc

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

لاحظ أنا وضعنا إسم المدخل في العقدة الفرعية فعند تشغيل البرنامج سيتم إستبدالة بقيمة المدخل كما سنرى لاحقاً

السطر السابق يقوم بتحديد عقدة الألبوم المدخل , مثلاً albume1 ثم أخذ أول عقدة منه file وتحميلها على الكائن filend

السطر السابع قمنا بتنظيف القائمة albume من أي عناصر موجودة فيها حتى ندخل إليها العناصر الجديدة من الملف

جملة while في السطر الثامن , تنفذ كود الدوارة ما دام filend لا يحمل القيمة null

السطر العاشر نقوم بإضافة بيانات العقدة إلى القائمة عن طريق الخاصية InnerText في العقدة

في السطر الحادي عشر نقوم بإختيار وتحميل العقدة التالية للعقدة الحالية , وهكذا حتى نصل لآخر عقدة ويتوقف تنفيذ كود الدوارة

في السطر الثالث عشر نقوم بإستدعاء إجراء نسخ القائمة albume إلى كائن المستعرض lv

بعد شرح هذا الإجراء بقي أن نختار المكان المناسب لإستدعائة

وأفضل مكان لذلك هو عندما يختار المستخدم إسم الألبوم من القائمة المنسدلة

إذهب إلى تصميم نافذة الألبومات وأنقر مزدوجاً على كائن القائمة المنسدلة

ستذهي إلى الشفرة , أكتب هناك إستدعاء الأجراء ReadAlbume

لا تنسى أن هذا الإجراء يتطلب مدخل من نوع نص يمثل الألبوم المختار

والألبوم المختار في هذه الحالة هو النص المكتوب على كائن القائمة المنسدلة Text

لذلك فإستدعاء الإجراء سيكون هكذا :

ReadAlbume(ac.Text);

ويصبح كود الإجراء كاملاً - إختيار إسم الألبوم من القائمة - هكذا :


void AcSelectedIndexChanged(object sender, System.EventArgs e)
{
ReadAlbume(ac.Text);
}

حيث أنه عند تشغيل البرنامج وإستدعاء الإجرء سيتم تغيير albumename في الإجراء إلى قيمة ac.Text

إجراء حذف الألبوم DeleteAlbume

يقوم هذا الإجراء بحذف بيانات الألبوم المختار من ملف XML

حيث يتطلب مدخل واحد من نوع نص , يمثل إسم الألبوم المراد حذفة

انسخ الكود التالي إلى شفرة نافذة الألبومات وتأكد من أنه خارج أي إجراء آخر :


void DeleteAlbume(string albumename)
{
try
{
if (MessageBox.Show("هل أنت متأكد من حذف / تعديل الألبوم ؟", "هل أنت متأكد", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
doc.Load(Application.StartupPath + "//albumes.xml");
doc["albumes"].RemoveChild(doc["albumes"][albumename]);
doc.Save(Application.StartupPath + "//albumes.xml");
ac.Items.RemoveAt(ac.SelectedIndex);
lv.Items.Clear();
}
}
catch
{
}
}

السطر الأول يحتوي على إسم الإجراء وإسم المدخل ونوعه string

السطر الخامس جملة if تقوم بإظهار رسالة تحذير للمستخدم بحيث يتم تأكيد الحذف , لاحظ عبارة إستدعاء الدالة :


MessageBox.Show("هل أنت متأكد من حذف / تعديل الألبوم ؟", "هل أنت متأكد", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)

العبارة إختلفة عن ما كنا نعرفه من قبل , ورغم أنها نفس التعليمة إلا أنها هذه المرة إستقبلت مدخلات أكثر

لذلك وظيفتها هذه المرة مختلفة قليلاً , المدخل الأول هو نص الرسالة كما عرفنا سابقاً

المدخل الثاني هو عنوان الرسالة الذي سيظهر في شريك العنوان

المدخل الثالث MessageBoxButtons.YesNo هو الأزرار المطلوب إظهارها في الرسالة حيث إخترنا YesNo

وهناك أيضاً OkCancel و هناك مجموعات أخرى من الأزرار

المدخل الرابع MessageBoxIcon.Question يمثل الأيقونه المراد إظهارها في الرسالة حيث إخترنا أيقونة السؤال Question

المدخل الخامس MessageBoxDefaultButton.Button2 يمثل الزر الإفتراضي , أي الزر الذي يكون التركيز عليه عند ظهور الرسالة

وقد إخترنا Button2 والذي سيكون في هذه الحالة زر No حيث سيكون الجواب الإفتراضي للرسالة هو No

وقد إخترنا No بدلا من Yes حتى يتأكد المستخدم من إختيارة قبل أن نحذف بيانات الألبوم

وإذا كانت نتيجة هذه الرسالة هي الموافقة DialogResult.Yes سيتم تنفيذ كود الحذف وإلا فلا

في السطر السابع تعليمة تحميل الملف لكائن doc

وفي السطر الثامن تعلمية إزالة عقدة الألبوم , حيث يتم إزالة عقدة بتحديد عقدتها الرئيسية ثم إستدعاء الإجراء RemoveChild

والعقدة الرئيسية لعقد الألبومات هي albumes لذلك تم إستدعاء إجراء الحذف منها

داخل قوسي إجراء الحذف العقدة المراد حذفها , وهي العقدة الذي إسمها هو المدخل albumename

الموجودة داخل العقدة الرئيسية albumes

في السطر التاسع تعليمة حفظ التغييرات على ملف XML بإستدعاء الإجراء Save من كائن doc

في السطر العاشر تعليمة حذف إسم الألبوم المحذوف من القائمة المنسدلة

وفي السطر الحادي عشر تعليمة تنظيف كائن المستعرض lv من ملفات الألبوم المحذوف

المكان المناسب لإستدعاء هذا الإجراء هو كود الزر "حذف الألبوم"

إذهب إلى تصميم نافذة الألبومات وانقر مزدوجاً على زر "حذف الألبوم" وأكتب إستدعاء إجراء الحذف هناك :


DeleteAlbume(ac.Text);

إجراء حفظ الألبوم WriteAlbume

هذا الإجراء سيقوم بتخزين محتويات كائن المستعرض lv إلى ملف XML

حيث يقوم الإجراء أولاً بإنشاء عقدة الألبوم , وتسميتها بالنص المكتوب على القائمة المنسدلة

ثم يقوم بإنشاء العقد الفرعية file والتي تحتوي على مسارات الملفات الموجودة في كائن المستعرض

وأيضاً يقوم الإجراء بحفظ التغيرات على ألبوم موجود أساساً , بحيث يقوم بحذفة أولاً من الملف ثم تخزين ألبوم جديد بنفس الإسم وبالبيانات المعدلة

إنسخ الكود التالي إلى شفرة نافذة الألبومات وتأكد من أنه خراج إلى إجراء آخر :

void WriteAlbume(string albumename)
{
try
{
doc.Load(Application.StartupPath + "//albumes.xml");
if (doc["albumes"][albumename]!=null)
{
doc["albumes"].RemoveChild(doc["albumes"][albumename]);
}
else
{
ac.Items.Add(ac.Text);
}
XmlNode albumend = doc.CreateElement(albumename);
for (int i = 0; i < albume.Count; i++)
{
XmlNode filend = doc.CreateElement("file");
XmlNode path = doc.CreateTextNode(albume[i]);
filend.AppendChild(path);
albumend.AppendChild(filend);
}
doc["albumes"].AppendChild(albumend);
doc.Save(Application.StartupPath + "//albumes.xml");
}
catch
{
MessageBox.Show("حدث خطأ أثناء محاولة حفظ بيانات الألبومات");
}
}

السطر الأول يحتوي على إسم الإجراء وإسم المدخل و نوعة string

السطر الخامس تعليمة تحميل الملف إلى كائن doc

السطر السادس عبارة if تختبر هل هناك عقدة للألبوم المحدد في ملف XML

فإذا كانت العقدة موجودة فالسطر الثامن يقوم بحذفها , حتى توضع بدلاً منها العقدة بالبيانات المعدلة

والحذف هنا هو للبيانات القديمة وخزن البيانات الجديدة كأنها إلبوم جديد بنفس الإسم

أما اذا لم يكن الألبوم موجود في الملف فإن كود الحذف لن يفعل شيئاً

لأنه ألوم جديد وبالتالي يضاف إسم هذا الألبوم إلى القائمة المنسدلة في السطر الثاني عشر

السطر الرابع عشر عرفنا متغير من نوع عقدة إسمه albumend وأسندنا له عقدة جديدة بعد إستدعاء تعليمة إنشاء العقدة


doc.CreateElement(albumename);

حيث يقوم الكود السابق بإنشاء عقدة جديدة في الملف إسمها هو المدخل albumename وهو إسم الألبوم المراد حفظه

السطر الخامس عشر عبارة for من الصفر إلى عدد عناصر القائمة albume لإنشاء عقد جديدة لكافة عناصرها

السطر السابع عشر عرفنا متغير من نوع عقدة إسمه filend حيث سيقوم بحمل عقدة جديدة إسمها file بعد إستدعاء تعليمة إنشاء العقدة


doc.CreateElement("file");

لاحظ لحد الآن أن لدينا عقدتين , العقدة albumend التي تحمل إسم الألبوم , والعقدة filend التي تحمل إسم file

بقي أن ندخل البيانات إلى العقدة file

السطر الثامن عشر عرفنا متغير من نوع عقدة وحملناه قيمة نصية من خلال إستدعاء إجراء إنشاء عقدة نصية

doc.CreateTextNode(albume[i]);

حيث يستقبل هذه الإجراء مدخل من نوع نص وهو البيانات المراد خزنها في العقدة , وهي العنصر الذي ترتيبة i من القائمة albume

الآن أصبح لدينا ثلاث عقد عقدة albumend التي تحمل إسم الألبوم , والعقدة filend التي تحمل إسم file وعقدة path التي تحمل مسار الملف من عنصر القائمة albume

إلى الآن لم يتم ربط العقد ببعضها البعض فهي إلى حد الآن عقد مستقلة ومنفصلة

يتم ربط عقدة فرعية بعقدة رئيسية من خلال إستدعاء الإجراء AppendChild من العقدة الرئيسية

وتمرير العقدة الفرعية كمدخل لهذا الإجراء , حيث في السطر التاسع عشر ربطنا العقدة path بعقدة filend

وأصبحت العقدة file تحتوي على بيانات , ثم في السطر العشرين ربطنا العقدة filend بما فيها بالعقدة albumend

وبتكرار العملية لكافة عناصر القائمة albume ستنتج لنا عقدة رئيسية إسمها بإسم المدخل albumename

تحتوي على عدة عقدة فرعية file تحتوي على مسارات الملفات في الألبوم

لاحظ أن عقدة الألبوم حتى الآن لم ترتبط بعقدة رئيسية , بل ربطناها بعقد فرعية فقط

في السطر التانب والعشرين ربطنا العقدة albumend بالعقدة الرئيسية في الملف albumes

وبهذا أصبح لدينا جميع العقد متصلة ومترابطة مع بعض ولم يبقى سوى حفظ التغيرات إلى الملف في السطر الثالث والعشرين

بقي أن نحدد مكان إستدعاء هذا الإجراء , إذهب إلى تصميم نافذة الأبومات وأنقر مزدوجاً على زر "حفظ الألبوم"

ستنتقل إلى الشفرة , أكتب هذا :

WriteAlbume(ac.Text);

بقي لدينا زر واحد وهو زر "البوم جديد" , إذهب إلى تصميم نافذة الألبومات وانقر مزوجاً على الزر "ألبوم جديد"

وأكتب داخلة هذه التعليمات :

lv.Items.Clear();
albume.Clear();
ac.Text = "";

في السطر الأول قمنا بتنظيف كائن المستعرض من أي ملفات موجودة مسبقاً

وفي السطر الثاني قمنا بتنظيف القائمة albume من أي عناصر موجودة مسبقاً

وفي السطر الثالث قمنا بتصفير النص المكتوب على القائمة المنسدلة , بحيث اصبح كل شيئ جاهز لإنشاء ألبوم جديد

شغل البرنامج الآن وقم بتجريب حفظ ألبوم و إسترجاع بياناته

ملاحظة: عند أنشاء ألبوم جديد تأكد من أن إسم الألبوم لا يحتوي على فراغات أو رموز غريبة

لأن أسماء العقد يجب أن لا تحتوي على فراغات أو رموز غريبة وإلا ظهرت رسالة الخطأ .

الواجب

أرسل التطبيق

.نهاية الدرس الحادي عشر.

..