تقييم الموضوع :
  • 2 أصوات - بمعدل 5
  • 1
  • 2
  • 3
  • 4
  • 5
التعامل مع ملفات xml بلغتي C#&VB
#1
بسم الله الرحمن الرحيم
((رب اشرح لي صدري ويسر لي امري واحلل عقدة من لساني يفقهوا قولي))
صدق الله العلي العظيم

السلام عليكم ورحمة الله وبركاته


الموضوع واضح من عنوانه وهو اننا سنتعامل مع ملف XML من حيث الانشاء والكتابة والتعديل والحذف والقراءة

XML: مختصر لكلمة (Extensible Markup Language) أي (لغة التوصيف الموسعة) وهي ليست لغة برمجة بل نستطيع ان نقول بانها بيانات او كتابات نصية تكتب بقواعد محددة متعارف عليها وهي شبيهة جدا بـHTML من حيث كتابة الاكواد كونها تستخدم الوسوم (Tags) في كتابة الاكواد لكنها غير مقيدة بكلمات محددة مثل الـHTML أي تستطيع كتابة أي كلمة لتكوين الجذور والعقد والعقد الفرعية ,كما أن الـXML تستخدم لتخزين البيانات بغض النظر عن كيفية عرضها وتتميز ملف الـXML بكونها صغيرة الحجم مقارنة بملفات قواعد البيانات وسهلة الوصول الى البيانات و التعامل معها ,من استعمالاتها خزن البيانات ومشاركتها من قبل قواعد البيانات حيث يمكن تصدير الجدول الى ملف XML واستيراد ملف XML.

تتكون ملف XML من جذر وعقدة وعقة فرعية وايضا يمكن تحديد صفة العقدة ايضا وتسمى هذه الخاصية بالـAttribute وتمثل صفة العقدة أو (العنصر) ,لنلق نظرة على ملفXML




وقد وفرت لنا مكتبة الـNet Framwork وسيلة للتعامل مع هكذا ملفات بسهولة تامة من خلال المكتبات XML أو XML.Linq حيث توفر هاتان المكتبتان كائنات ودوال تمكننا من التعامل مع ملفات الـXML من حيث انشاء ملف او التعديل على ملف........ ألخ.

والان بسم الله سنبدأ بعمل مثال نتعلم من خلاله كتابة ملفات XML

اولا نكون مشروع جديد ونصممه بالشكل التالي:




نأتي الى الاكواد:

المكتبات المطلوبة:


PHP كود :
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;

using System.IO;
using System.Xml;
using System.Xml.Linq

نصمم Class باسم Emp بالشكل التالي:

PHP كود :
#region Emp Class
 
       class Emp
        
{
 
           public int ID getset; }
 
           public string Name getset; }
 
           public string Gender getset; }
 
           public int Age getset; }
 
           public string Imgstring getset; }
 
       }
#endregion 


المتغيرات العالمة:



PHP كود :
#region المتغيرات العامة
 
       private XElement _xel,_empinfo_id_name_age,_image;
 
       private readonly XmlDocument _doc = new XmlDocument();
 
       private XmlNode _node;
 
       private readonly List<Emp _emp = new List<Emp>();
 
       private int _pos;
 
       private const string Xpath = @"D:\emp.xml";
 
       private string _imgstr "";
#endregion 

دالة ملئ الحقول في النموذج:

PHP كود :
#region Fill Mthod
 
       private void Fill(int pos)
 
       {
 
           id_txt.Text _emp[pos].ID.ToString(CultureInfo.InvariantCulture);
 
           name_txt.Text _emp[pos].Name;
 
           age_txt.Text _emp[pos].Age.ToString(CultureInfo.InvariantCulture);
 
           pic.Image StringToImage(_emp[pos].Imgstring);
 
           if (_emp[pos].Gender == "ذكر")
 
               Male_rdbtn.Checked true;
 
           else
                Female_rdbtn
.Checked true;
 
       }
#endregion 

دالة تحويل الصورة الى سلسلة نصية لسهولة خزنها في ملف xml :

PHP كود :
private static string ImageToString(Image img)
 
       {
 
           var m = new MemoryStream();
 
           img.Save(mSystem.Drawing.Imaging.ImageFormat.Jpeg);
 
           return Convert.ToBase64String(m.ToArray());
 
       

دالة استرجاع الصورة من هيئتها النصية :

PHP كود :
private static Image StringToImage(string imgstring)
 
       {
 
           var imgbytes Convert.FromBase64String(imgstring);
 
           var m = new MemoryStream(imgbytes);
 
           return Image.FromStream(m);
 
       

كود انشاء ملف XML واضافة العقد اليه:

PHP كود :
private void write_btn_Click(object senderEventArgs e)
 
       {
 
           var found false;
 
           if (File.Exists(Xpath))
 
           {
 
               _xel XElement.Load(Xpath);
 
               //لعدم تكرار موظف بنفس التسلسل
 
               foreach (var t in _emp)
 
               {
 
                   found t.ID.ToString(CultureInfo.InvariantCulture) == id_txt.Text;
 
               }
 
           }
 
           else
                _xel 
= new XElement("Info");

 
           if (!found)
 
           {
 
               var gender Male_rdbtn.Checked "ذكر" "انثى";

 
               _empinfo = new XElement("EmpInfo");
 
               _empinfo.SetAttributeValue("EmpInfo""EmployeeInformation");

 
               _id = new XElement("EId"id_txt.Text);

 
               _name = new XElement("EName"name_txt.Text);
 
               _name.SetAttributeValue("Gender"gender);

 
               _age = new XElement("EAge"age_txt.Text);

 
               _image = new XElement("EImage"_imgstr);

 
               _empinfo.Add(_id_name_age_image);
 
               _xel.Add(_empinfo);
 
               _xel.Save(Xpath);
 
               _pos _xel.Nodes().Count() - 1;
 
               read_btn_Click(sendere);
 
           }
 
           else
            
{
 
               MessageBox.Show(@"هذا التسلسل موجود ,اختر تسلسلا آخر""");
 
           }
 
       

نأتي الى شرح الكود أعلاه:

اولا نتأكد ما اذا كان الملف موجود مسبقا فنقوم بقرائته فقط ومن ثم نتأكد من عدم تكرار التسلسل لاكثر من مرة ونقوم باضافة العناصر اليها أما اذا كان الملف غير موجود فنقوم بانشاء الجذر الرئيسي للملف باسم Info وعقدة فرعية باسم EmpInfo تضم العقد التالية: (ID, Name, Age, Image) والعقدة Name لديها خاصية باسم Gender والعقدة EmpInfo لديها خاصية باسم EmpInfo وتستطيع تغيير الصفات أو الخصائص كما تشاء. وفي الاخير نقوم بحفظ الملف.

طبعا هنالك عدة طرق لاضافة عناصر الى ملف XML وانا اخترت الكائن XElement ضمن مجال الاسماء   XML.Linq   فهي برأيي اسهل طريقة لانشاء ملف واضافة العناصر والصفات لعنصر معين من العناصر.

كود القراءة:



PHP كود :
private void read_btn_Click(object senderEventArgs e)
 
       {
 
           srch_btn.Enabled true;
 
           _emp.Clear();
 
           if (!File.Exists(Xpath)) return;
 
           _doc.Load(Xpath);
 
           var xmlElement _doc["Info"];
 
           if (xmlElement != null_node xmlElement["EmpInfo"];
 
           while (_node != null)
 
           {
 
               var element _node["EId"];
 
               if (element != null)
 
               {
 
                   var xmlElement1 _node["EName"];
 
                   if (xmlElement1 != null)
 
                   {
 
                       var element1 _node["EAge"];
 
                       if (element1 != null)
 
                       {
 
                           var xmlElement2 _node["EImage"];
 
                           if (xmlElement2 != null)
 
                               _emp.Add(
 
                                   new Emp
                                    
{
 
                                       ID int.Parse(element.InnerText),
 
                                       Name xmlElement1.InnerText,
 
                                       Gender xmlElement1.Attributes["Gender"].InnerText,
 
                                       Age int.Parse(element1.InnerText),
 
                                       ImgstringxmlElement2.InnerText 

                                    
}
 
                                   );
 
                       }
 
                   }
 
               }
 
               _node _node.NextSibling;
 
           }
 
           Fill(_pos);
 
       

شرح الكود:

ايضا هنالك طرق عدة للقراءة هنا استخدمت الكائنين XmlNode, XmlDocument الموجودين ضمن مجال الاسماء XML ,اولا نسند العقدة الرئيسية والعقدة التي بعدها الى متغير من الكائن XmlNode أي نسند العقدة EmpInfo الى المتغير node ومن خلاله نقوم بالمرور على العقد التي تحتويها واستخراج محتواها ومن ثم المرور على كل العقد باستخدام الخاصية NextSibling أي العقدة التالية ,أما قراءة محتوى العقدة فتتم عن طريق خاصية InnerText بعد ذكر اسم العقدة أما الوصول الى صفة عقدة معينة اولا نذكر اسم العقدة ومن ثم اسم الخاصية ومن ثم InnerText. فكما ترون سهلة جدا الوصول الى محتوى أي عقدة في الملف.

كود التعديل:


PHP كود :
private void update_btn_Click(object senderEventArgs e)
 
       {
 
           var xmlElement _doc["Info"];
 
           if (xmlElement != null_node xmlElement["EmpInfo"];
 
           while (_node != null)
 
           {
 
               if (_node["EId"] != null && _node["EId"].InnerText == id_txt.Text)
 
               {
 
                   _emp[_pos].ID int.Parse(_node["EId"].InnerText id_txt.Text);
 
                   _emp[_pos].Name _node["EName"].InnerText name_txt.Text;
 
                   if (Male_rdbtn.Checked)
 
                   {
 
                       _emp[_pos].Gender _node["EName"].Attributes["Gender"].InnerText Male_rdbtn.Text;
 
                   }
 
                   else
                    
{
 
                       _emp[_pos].Gender _node["EName"].Attributes["Gender"].InnerText Female_rdbtn.Text;
 
                   }
 
                   _emp[_pos].Age int.Parse(_node["EAge"].InnerText age_txt.Text);
 
                   _emp[_pos].Imgstring _node["EImage"].InnerText ImageToString(pic.Image);

 
               }
 
               _node _node.NextSibling;
 
           }
 
           _doc.Save(Xpath);
 
           read_btn_Click(sendere);
 
       

اعتقد الكود سهل جدا ولا يحتاج الى شرح

كود الحذف:


PHP كود :
private void delete_btn_Click(object senderEventArgs e)
 
       {
 
           var xmlElement _doc["Info"];
 
           if (xmlElement != null_node xmlElement["EmpInfo"];
 
           while (_node != null)
 
           {
 
               var element _node["EName"];
 
               if (element != null && element.InnerText == name_txt.Text)
 
               {
 
                   if (_node.ParentNode != null_node.ParentNode.RemoveChild(_node);
 
                   _emp.RemoveAt(int.Parse(id_txt.Text) - 1);
 
               }
 
               _node _node.NextSibling;
 
           }
 
           _doc.Save(Xpath);
 
           _pos--;
 
           if (_pos 0)
 
               _pos 0;
 
           Fill(_pos);
 
       


شرح الكود:

نقوم بحذف عقدة معينة حسب الاسم عن طريق هذا السطر:



PHP كود :
node.ParentNode.RemoveChild(node); 


هذا السطر بحذف العقدة (EmpInfo) التي تنتمي للعقدة الرئيسية Info وعند حذف العقدة (EmpInfo) ستحذف جميع العقد التي تحتويها ومن ضمنها محتوى العقد او العناصر.

فـ ParentNode=Info
وRemoveChild=EmpInfo

كود البحث:



PHP كود :
private void srch_btn_Click(object senderEventArgs e)
 
       {
 
           if (!File.Exists(Xpath)) return;
 
           _doc.Load(Xpath);
 
           var xmlElement _doc["Info"];
 
           if (xmlElement != null_node xmlElement["EmpInfo"];
 
           while (_node != null)
 
           {
 
               if (_node["EName"].InnerText == Srch_txt.Text.Trim())
 
               {
 
                   id_txt.Text _node["EId"].InnerText;
 
                   name_txt.Text _node["EName"].InnerText;
 
                   string gender _node["EName"].Attributes["Gender"].InnerText;
 
                   age_txt.Text _node["EAge"].InnerText;
 
                   pic.Image StringToImage(_node["EImage"].InnerText);
 
                   _pos int.Parse(id_txt.Text) - 1;

 
                   if (gender == "ذكر")
 
                       Male_rdbtn.Checked true;
 
                   else
                        Female_rdbtn
.Checked true;
 
               }
 
               _node _node.NextSibling;
 
           }
 
       

كود جلب الصورة:

PHP كود :
private void button1_Click(object senderEventArgs e)
 
       {
 
           ofD.Filter = @"Image Files (*.bmp;*.jpg;*.tif;*.png)|*.bmp;*.jpg;*.tif;*.png";
 
           if (ofD.ShowDialog() == DialogResult.OK)
 
           {
 
               pic.Image Image.FromFile(ofD.FileName);
 
               _imgstr ImageToString(pic.Image);
 
           }
 
       

كود التقرير:


PHP كود :
private void button2_Click(object senderEventArgs e)
 
       {
 
           var rf = new reportform();
 
           rf.rv.LocalReport.EnableExternalImages true;


 
           var ds = new Microsoft.Reporting.WinForms.ReportDataSource("emp"_emp);

 
           var param = new List<Microsoft.Reporting.WinForms.ReportParameter>
 
           {
 
               new Microsoft.Reporting.WinForms.ReportParameter("id",
 
                   _emp[_pos].ID.ToString(CultureInfo.InvariantCulture)),
 
               new Microsoft.Reporting.WinForms.ReportParameter("name"_emp[_pos].Name),
 
               new Microsoft.Reporting.WinForms.ReportParameter("age",
 
                   _emp[_pos].Age.ToString(CultureInfo.InvariantCulture))
 
           };

 
           var im StringToImage(_emp[_pos].Imgstring);
 
           const string temp "c:\\Pics\\temp.jpg";
 
           im.Save(temp);

 
           param.Add(new Microsoft.Reporting.WinForms.ReportParameter("image""file:///c:\\Pics\\temp.jpg"));

 
           rf.rv.LocalReport.DataSources.Add(ds);
 
           rf.rv.LocalReport.SetParameters(param);
 
           
            rf
.ShowDialog();

 
           File.Delete(temp);
 
       

شرح الكود:

اولا وبما ان حقل واحد عبارة عن صورة وبما اننا نتعامل مع تقارير Microsoft يجب ان نفعل خاصية External Image في البداية
ومن ثم نقوم بتحديد مصدر البيانات للتقرير وبعد ذلك نمرر القيم كباراميترات الى تقرير
أما عن كيفية تمرير الصورة الى التقرير اولا ننشئ باراميرت نصي يستقبل مسار الصورة ومن ثم ننشئ كائن image في التقرير ونسند قيمة المسار الى كائن الـimage
واثناء طباعة الصورة نقوم بخزنها بشكل مؤقت وتمرير مسارها الى التقرير قبل حذفها

بقية الاكواد:


PHP كود :
private void next_btn_Click(object senderEventArgs e)
 
       {
 
           if (_pos >= _emp.Count 1) return;
 
           _pos++;
 
           Fill(_pos);
 
       }

 
       private void prev_btn_Click(object senderEventArgs e)
 
       {
 
           if (_pos <= 0) return;
 
           _pos--;
 
           Fill(_pos);
 
       }

 
       private void last_btn_Click(object senderEventArgs e)
 
       {
 
           Fill(_pos _emp.Count 1);
 
       }

 
       private void first_btn_Click(object senderEventArgs e)
 
       {
 
           Fill(_pos 0);
 
       }

 
       private void clear_btn_Click(object senderEventArgs e)
 
       {
 
           foreach (Control c in groupBox1.Controls)
 
           {
 
               if (c.GetType() == typeof(TextBox))
 
               {
 
                   c.Text "";
 
               }
 
               else if (c.GetType() == typeof(RadioButton))
 
               {
 
                   var r = (RadioButton)c;
 
                   r.Checked false;
 
               }
 
               else if (c.GetType() == typeof(PictureBox))
 
               {
 
                   var p = (PictureBox)c;
 
                   p.Image null;
 
               }
 
           }
 
       }

 
       private void linkLabel1_LinkClicked(object senderLinkLabelLinkClickedEventArgs e)
 
       {
 
           System.Diagnostics.Process.Start("http://vb4arb.com/vb/forum.php");
 
       }

 
       private void Form1_FormClosed(object senderFormClosedEventArgs e)
 
       {
 
           GC.Collect();
 
       

المثال في المرفقات بلغتي C# & VB

الحمد لله ولاتنسونا من صالح دعواتكم


الملفات المرفقة
.zip   XML_Manipulating.zip (الحجم : 88.65 ك ب / التحميلات : 429)
.zip   XML_Mnipulating_VB.zip (الحجم : 116.93 ك ب / التحميلات : 529)
الرد }}}
#2
مقال مفيد جدااا

وانا استفدت منه كثيرا لما كان في نسخته السابقة على المنتدى القديم


جزاك الله خيرا

(يثبت)
الرد }}}
تم الشكر بواسطة: Sajad , Sajad
#3
السلام عليكم ورحمة الله وبركاته

جميل جدآآ بارك الله بك وجعله بميزان حسناتك

لكن الموضوع مكتوب لغتي C#&vb والشرح فقط للــC#

موفق
الرد }}}
تم الشكر بواسطة:
#4
جميل جداً ومثال رائع .. سؤال كم تحتمل القاعدة xml بيانات . الاكسس 2 جيجا .

أيضا القاعدة XML كم تدعم اتصال على الشبكة

ولك جزيل الشكر

تحياتي
الرد }}}
تم الشكر بواسطة:
#5
(30-10-13, 08:47 PM)3booody كتب : السلام عليكم ورحمة الله وبركاته

جميل جدآآ بارك الله بك وجعله بميزان حسناتك

لكن الموضوع مكتوب لغتي C#&vb والشرح فقط للــC#

موفق

بعد اذن الاخ Sajad ,, هذا شرح ايضاً بلغتي C# & VB.net

http://dotnet4beg.blogspot.com/2013/08/xml-system.html
سبحان الله وبحمده سبحان الله العظيم

الرد }}}
تم الشكر بواسطة: Sajad , 3booody , عبد الله
#6
السلام عليكم ورحمة الله وبركاته

إقتباس :لكن الموضوع مكتوب لغتي C#&vb والشرح فقط للــC#

الاخ 3booody بما ان المقالة في قسم الـC#.NET فالاكواد والشرح تكون بلغة C#.NET لكن في المرفقات هنالك مثال بلغة VB.NET فتستطيع ان تستفيد من المثال وتفهم الشرح لانه حسب معرفتي بان اوجه التشابه بين اللغتين هي 90% هذا ان لم تكن اكثرSmile

على كل جزاكم الله خيرا اخواني على تعليقاتكم الجميلة وارجو انكم استفدتم من المقال.

بالنسبة لسؤال الاخ العزابي صراحة لا علم لي بمدى حجم البيانات التي يمكن ان تحتملها ولم افهم السؤال الثاني!

واشكر الاخ Abdullah0991 على موضوعه وشرحه الرائع

تحياتي
الرد }}}
تم الشكر بواسطة: 3booody , Abdullah0991 , الشاكي لله
#7
جزاك الله ووالديك الفردوس الأعلى
فاعلم أنه لا إله إلا الله
الرد }}}
تم الشكر بواسطة: Sajad
#8
بارك الله فيك اجمل منتدى من حيث الشروحات الهادفة اجتمع الاساتذه فيه حفظهم الله
الرد }}}
تم الشكر بواسطة: Sajad



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم