تقييم الموضوع :
  • 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 
= 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 
= 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 
= (RadioButton)c;
                    
r.Checked false;
                }
                else if (
c.GetType() == typeof(PictureBox))
                {
                    var 
= (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 ك ب / التحميلات : 224)
.zip   XML_Mnipulating_VB.zip (الحجم : 116.93 ك ب / التحميلات : 318)
الرد }}}}
#2
مقال مفيد جدااا

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


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

(يثبت)
الرد }}}}
تم الشكر بواسطة:
#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


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  [سلسلة التعامل مع الويب] تحليل الصفحات باستخدام HtmlAgilityPack الشاكي لله 9 1,235 25-09-16, 12:19 PM
آخر رد: ابراهيم كركوكي
  [سلسلة التعامل مع الويب] - ارسال الطلبات HttpWebRequset الشاكي لله 14 4,825 02-06-16, 11:21 AM
آخر رد: CLARO
  [مثال] استخدام ملفات الـ Resources ربيع 23 2,802 20-03-16, 09:02 PM
آخر رد: ربيع
  التعامل مع ملفات zip الشاكي لله 4 830 12-02-16, 02:48 PM
آخر رد: nani49
  [سلسلة التعامل مع الويب] - تبادل البيانات بين المستخدمين (تمهيدي) الشاكي لله 6 1,180 23-08-13, 09:10 PM
آخر رد: الشاكي لله
  التعامل مع الأجهزة الخارجية عن طريق المنفذ Serial Port Blue Sky 1 1,198 01-10-12, 07:57 PM
آخر رد: Blue Sky

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


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