بسم الله الرحمن الرحيم
((رب اشرح لي صدري ويسر لي امري واحلل عقدة من لساني يفقهوا قولي))
صدق الله العلي العظيم
السلام عليكم ورحمة الله وبركاته
((رب اشرح لي صدري ويسر لي امري واحلل عقدة من لساني يفقهوا قولي))
صدق الله العلي العظيم
السلام عليكم ورحمة الله وبركاته
الموضوع واضح من عنوانه وهو اننا سنتعامل مع ملف 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 { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int Age { get; set; }
public string Imgstring { get; set; }
}
#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(m, System.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 sender, EventArgs 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(sender, e);
}
else
{
MessageBox.Show(@"هذا التسلسل موجود ,اختر تسلسلا آخر", "");
}
}
نأتي الى شرح الكود أعلاه:
اولا نتأكد ما اذا كان الملف موجود مسبقا فنقوم بقرائته فقط ومن ثم نتأكد من عدم تكرار التسلسل لاكثر من مرة ونقوم باضافة العناصر اليها أما اذا كان الملف غير موجود فنقوم بانشاء الجذر الرئيسي للملف باسم Info وعقدة فرعية باسم EmpInfo تضم العقد التالية: (ID, Name, Age, Image) والعقدة Name لديها خاصية باسم Gender والعقدة EmpInfo لديها خاصية باسم EmpInfo وتستطيع تغيير الصفات أو الخصائص كما تشاء. وفي الاخير نقوم بحفظ الملف.
طبعا هنالك عدة طرق لاضافة عناصر الى ملف XML وانا اخترت الكائن XElement ضمن مجال الاسماء XML.Linq فهي برأيي اسهل طريقة لانشاء ملف واضافة العناصر والصفات لعنصر معين من العناصر.
كود القراءة:
PHP كود :
private void read_btn_Click(object sender, EventArgs 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),
Imgstring= xmlElement2.InnerText
}
);
}
}
}
_node = _node.NextSibling;
}
Fill(_pos);
}
شرح الكود:
ايضا هنالك طرق عدة للقراءة هنا استخدمت الكائنين XmlNode, XmlDocument الموجودين ضمن مجال الاسماء XML ,اولا نسند العقدة الرئيسية والعقدة التي بعدها الى متغير من الكائن XmlNode أي نسند العقدة EmpInfo الى المتغير node ومن خلاله نقوم بالمرور على العقد التي تحتويها واستخراج محتواها ومن ثم المرور على كل العقد باستخدام الخاصية NextSibling أي العقدة التالية ,أما قراءة محتوى العقدة فتتم عن طريق خاصية InnerText بعد ذكر اسم العقدة أما الوصول الى صفة عقدة معينة اولا نذكر اسم العقدة ومن ثم اسم الخاصية ومن ثم InnerText. فكما ترون سهلة جدا الوصول الى محتوى أي عقدة في الملف.
كود التعديل:
PHP كود :
private void update_btn_Click(object sender, EventArgs 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(sender, e);
}
اعتقد الكود سهل جدا ولا يحتاج الى شرح
كود الحذف:
PHP كود :
private void delete_btn_Click(object sender, EventArgs 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 sender, EventArgs 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 sender, EventArgs 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 sender, EventArgs 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 sender, EventArgs e)
{
if (_pos >= _emp.Count - 1) return;
_pos++;
Fill(_pos);
}
private void prev_btn_Click(object sender, EventArgs e)
{
if (_pos <= 0) return;
_pos--;
Fill(_pos);
}
private void last_btn_Click(object sender, EventArgs e)
{
Fill(_pos = _emp.Count - 1);
}
private void first_btn_Click(object sender, EventArgs e)
{
Fill(_pos = 0);
}
private void clear_btn_Click(object sender, EventArgs 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 sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("http://vb4arb.com/vb/forum.php");
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
GC.Collect();
}
المثال في المرفقات بلغتي C# & VB
الحمد لله ولاتنسونا من صالح دعواتكم