ف اإلصدارات السابقة من.Net Framework كان التعامل مع ال Extensible Mar kup ( XML )Language عمل ة بط ئة و صعبة و كان التعامل معها تبع لما سمى W3C DOM API )سنتكلم عنها الحقا ( ح ث كان على المبرمج ف هذا ال model أن قوم بإنشاء مستند XML دائما حتى و إن لم كن لد ه سوى عنصر XML وح د و هذا عرف ب document-centric و هذا من األمور المزعجة فعال. بعد أن صدرت.Net Framework 3.5 اختفت معظم المشاكل السابقة ف التعامل مع لغة XML و أصبح من الممكن كتابة عناصر دون الحاجة إلى إنشاء مستند كامل أي element-centric باإلضافة إلى االستفادة من األنواع المجهولة للمتحوالت types( )anonymous و إمكان ة استخدام تقن ة LINQ مع عناصر ومستندات XML أي أصبح إنشاء ملفات هذه اللغة و التعامل أسهل و أسرع من أي وقت مضى. حسنا لنبدأ اآلن ببعض األمثلة لد نا ملف XML التال و سنحاول كتابته أوال باستخدامAPI DOM و من ثم باستخدام الصفوف الت توفرها لناLINQ لنرى الفارق ب نهما: الملف باستخدام : DOM API <BookParticipants> <BookParticipant type="author"> <FirstName>Joe</FirstName> <LastName>Rattz</LastName> <BookParticipant type="editor"> <FirstName>Ewan</FirstName> <LastName>Buckingham</LastName> </BookParticipants> XmlElement xmlbookparticipant; XmlAttribute xmlparticipanttype; XmlElement xmlfirstname; XmlElement xmllastname; // First, I must build an XML document. XmlDocument xmldoc = new XmlDocument(); // I'll create the root element and add it to the document. XmlElement xmlbookparticipants = xmldoc.createelement("bookparticipants"); xmldoc.appendchild(xmlbookparticipants); // I'll create a participant and add it to the book participants list. xmlbookparticipant = xmldoc.createelement("bookparticipant"); xmlparticipanttype = xmldoc.createattribute("type");
xmlparticipanttype.innertext = "Author"; xmlbookparticipant.attributes.append(xmlparticipanttype); xmlfirstname = xmldoc.createelement("firstname"); xmlfirstname.innertext = "Joe"; xmlbookparticipant.appendchild(xmlfirstname); xmllastname = xmldoc.createelement("lastname"); xmllastname.innertext = "Rattz"; xmlbookparticipant.appendchild(xmllastname); xmlbookparticipants.appendchild(xmlbookparticipant); // I'll create another participant and add it to the book participants list. xmlbookparticipant = xmldoc.createelement("bookparticipant"); xmlparticipanttype = xmldoc.createattribute("type"); xmlparticipanttype.innertext = "Editor"; xmlbookparticipant.attributes.append(xmlparticipanttype); xmlfirstname = xmldoc.createelement("firstname"); xmlfirstname.innertext = "Ewan"; xmlbookparticipant.appendchild(xmlfirstname); xmllastname = xmldoc.createelement("lastname"); xmllastname.innertext = "Buckingham"; xmlbookparticipant.appendchild(xmllastname); xmlbookparticipants.appendchild(xmlbookparticipant); XElement xbookparticipants = new XElement("BookParticipants", new XElement("BookParticipant", new XAttribute("type", "Author"), new XElement("FirstName", "Joe"), new XElement("LastName", "Rattz")), new XElement("BookParticipant", new XAttribute("type", "Editor"), new XElement("FirstName", "Ewan"), new XElement("LastName", "Buckingham"))); Console.WriteLine(xBookParticipants.ToString()); الملف باستخدام : LINQ أعتقد أن الصورة لد كم اآلن أصبحت واضحة أكثر..الحظوا صعوبة الكتابة بالطر قة األولى باإلضافة إلى أنه من الصعب جدا توقع عناصرXML الت ستنتج ب نما ف الطر قة الثان ة سنكتب أسطرا أقل باإلضافة إلى أنه أصبح من الواضح جدا شكل الخرج الناتج. كما سبق و قلت ف المقدمة فإنك إذا أردت إنشاء عنصر XML وح د باستخدام W3C DOM model API فإنك ستكون مضطرا إلى إنشاء مستند XML جد د كما ل : // With the original W3C DOM API, you could not simply create an XML element, XmlElement; you must // have an XML document, XmlDocument, from which to create it: XmlDocument myxmldoc = new XmlDocument(); XmlElement xmlbookparticipant1 = myxmldoc.createelement("bookparticipant"); أما اآلن مع LINQ فأنت غ ر مضطر لذلك و تستط ع إنشاء عنصر وح د بسهولة :
// The new LINQ-enabled XML API allows you to instantiate an element itself without creating an XML document: XElement xebookparticipant = new XElement("BookParticipant"); حسنا و ماذا إذا كنا نر د مستند XML و ل س عنصرا فقط المثال التال س ج ب عن هذا التساؤل: XDocument doc = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), new XComment("Sample RSS Feed"), new XElement("rss", new XAttribute("version", "2.0"), new XElement("channel", new XElement("title", "RSS Channel Title"), new XElement("description", "RSS Channel Description."), new XElement("link", "http://aspiring-technology.com"), new XElement("item", new XElement("title", "First article title"), new XElement("description", "First Article Description"), new XElement("pubDate", DateTime.Now.ToUniversalTime()), new XElement("guid", Guid.NewGuid())), new XElement("item", new XElement("title", "Second article title"), new XElement("description", "Second Article Description"), new XElement("pubDate", DateTime.Now.ToUniversalTime()), new XElement("guid", Guid.NewGuid())) ) ) ); ح ث: XDocument إلنشاء مستند XML جد د. XElement إلنشاء عنصر XML جد د )قد كون داخل عنصر آخر(. XComment إلضافة التعل قات. XAttribute إلضافة صفة لعنصر ما. قمنا بكتابة ملف XML و لكن لن نستف د ش ئا ما لم نكن قادر ن على تخز نه و تحم له الحقا لذلك لتخز ن الملف السابق نستخدم التابعSave كما ل : doc.save(@"e:\file.xml"); كل ما نحتاجه هو تمر ر المسار الذي نر د التخز ن ف ه إلى التابعSave. instance method أي نستدع ه من أجل Object مع ن. الحظ أ ضا أن هذا التابع هو
عندما نفتح الملف الذي حفظناه لتونا سنشاهد أنه قد تمت كتابته بتنس قXML الذي اعتدنا عل ه و لكن مكننا أن نلغ هذه الخاص ة و نحفظ الملف كتسلسل نص عادي و ذلك باستخدامSaveOptions و اخت ار DisableFormatting كما ل : و س كون الملف كما توقعتم أي : doc.save(@"e:\file.xml",saveoptions.disableformatting); <?xml version="1.0" encoding="utf-8" standalone="yes"?><!--sample RSS Feed-- ><rss version="2.0"><channel><title>rss Channel Title</title><description>RSS Channel Description.</description><link>http://aspiringtechnology.com</link><item><title>First article title</title><description>first Article Description</description><pubDate>2010-03- 19T21:06:11.307319Z</pubDate><guid>ce13e62b-fec4-4c89-88ccbdf52127a4bf</guid></item><item><title>Second article title</title><description>second Article Description</description><pubDate>2010-03- 19T21:06:11.3093192Z</pubDate><guid>606ddb72-7806-4ed1-910d- 95cd0eb5a0d9</guid></item></channel></rss> ال أعتقد أن أحدا فضل شكل الملف هكذا! حسنا لنعد قل ال إلى المثال األول عندما تكلمنا عن DOM API و لنحاول طباعة الملف على الشاشة لنشاهد ك ف س كون الخرج و لنكتب : Console.WriteLine(xmlDoc.ToString); System.Xml.XmlDocument 3 و! Ctrl+F5 : الخرج : 2 حسنا لنعد إلى ثالثة و ننفذ لنرى النت جة :1 لألسف فإن استخدام ToString هنا لن جدي نفعا إذا لنحاول مع تابع آخر خاص بهذا األمر : الخرج س كون على النحو التال : Console.WriteLine(xmlDoc.OuterXml); <BookParticipants><BookParticipant type="author"><firstname>joe</firstname><lastname>rattz</lastname></bookparti cipant><bookparticipanttype="editor"><firstname>ewan</firstname><lastname>buc kingham</lastname></bookparticipants> أما لو عدنا إلى المثال التال عندما كتبنا عناصر XML باستخدام الصف XElement و حاولنا استخدام ToString إلظهار النتائج سنحصل على النت جة التال ة : <BookParticipants> <BookParticipant type="author">
<FirstName>Joe</FirstName> <LastName>Rattz</LastName> <BookParticipant type="editor"> <FirstName>Ewan</FirstName> <LastName>Buckingham</LastName> </BookParticipants> الحظ االختالف ف تنس ق الملف. هذا بالنسبة للحفظ أما بالنسبة لتحم ل ملفXML ما إلى برنامجنا سنقوم باستخدام التابع Load وهو تابع Static أي نستدع ه من أجل الصف و ل س من أجل كائن منه..بفرض أننا قمنا بإنشاء ملف ف المشروع باسم TestFile و نر د تحم له اآلن فإننا نكتب : XDocument xmldoc1 = XDocument.Load("TestFile.xml"); بالطبع فهنالك العد د من الخ ارات أثناء تحم ل الملف سنتكلم عنها الحقا. بالعودة قل ال إلى الصف XElement سنجد أننا استخدمنا البان الذي أخذ وسط ن األول عبر عن اسم ال Tag و الثان عبر عن المحتوى داخلها أي إذا أخذنا المثال التال : ح ث س كون الخرج : Console.WriteLine(new XElement("Name","Hammod")); أما إذا أردنا الق مة المحتواة ف هذا العنصر فلن نحتاج أكثر من استدعاء التابعValue : <Name>Hammod</Name> XElement name = new XElement("Author", "Hammod"); Console.WriteLine(name.Value); لننتقل اآلن إلى ناح ة أخرى فLINQ و لنفترض أنه لد نا مصفوفة مكونة من مئة اسم نر د كتابتها على شكل ملف XML كما ف المثال السابق تماما. هذه عمل ة مضن ة حقا! لذلك البد من طر قة ما لكتابتها بسرعة و فاعل ة و بأقل عدد ممكن من أسطر الكود من المؤكد أنكم اآلن تفكرون ف الحلقات و لكن ما رأ كم بتجربة أمر آخر لنشاهد المثال التال الذي حوي أربعة أسماء و مكن تعم مه ألعداد أكبر طبعا : string[] names = { "M.Hammod", "Golden Man", "Mohammed_807", "Nawwar(music man)" }; XElement OurGroupMembers = new XElement("OurGroup",
from n in names select new XElement("Name",n)); Console.WriteLine(OurGroupMembers); الحظوا ما الذي قمنا به و ك ف استطعنا بناء الملف باستعمال select من مصفوفة األسماء و النت جة الت ستظهر ه : <OurGroup> <Name>M.Hammod</Name> <Name>Golden Man</Name> <Name>Mohammed_807</Name> <Name>Nawwar(music man)</name> لندخل ف العمق قل ال و لنفرض أننا قمنا بتغ ر أحد األسماء ف المصفوفة بعد بناء الملف فما الذي س حصل </OurGroup> string[] names = { "M.Hammod", "Golden Man", "Mohammed_807", "Nawwar(music man)" }; XElement OurGroupMembers = new XElement("OurGroup", from n in names select new XElement("Name",n)); names[3] = "Mu_Nizar"; Console.WriteLine(OurGroupMembers); الخرج س كون معتمدا على اإلجابة عن السؤال التال : متى تم بناء الملف هل تم بناؤه مباشرة أم تم تأج له اإلجابة أننا عندما نستخدم الصف XElement تم ذلك مباشرة لذلك لن ظهر أي تغ ر ف بن ة الملف : <OurGroup> <Name>M.Hammod</Name> <Name>Golden Man</Name> <Name>Mohammed_807</Name> <Name>Nawwar(music man)</name> </OurGroup> حسنا ما الحل إذا لتغ ر بن ة الملف باستعمال الكود السابق الحل باستخدامXStreamingElement بدال من : XElement XStreamingElement OurGroupMembers1 = new XStreamingElement("OurGroup", from n in names
names[3] = "Mu_Nizar"; Console.WriteLine(OurGroupMembers1); select new XElement("Name", n)); هنا سنحصل على التغ ر المنشود و ستكون النت جة : <OurGroup> <Name>M.Hammod</Name> <Name>Golden Man</Name> <Name>Mohammed_807</Name> <Name>Mu_Nizar</Name> </OurGroup> كاوج هذي مجرد مقدمت بسيطت عه LINQ to XML على الرغم مه أوىا لم وتحدث عه LINQ حتى اآلن! و لكه أصبح لديىا فكرة جيدة عه إمكاويت إوشاء مستىداث XML بسهىلت و يسر بىاسطتها و الهدف أن وعلم أن LINQ ليسج لمجرد االستعالماث فقط. في المرة القادمت إن شاء هللا سىتحدث بتفصيل أكبر عه LINQ و وكتب أمثلت لتبيه لىا فعاليت التعامل مع ال XML فيها. Happy Programming! ----------------------------------------------------------------------------- HammooD 2010-03-19 m-khaled89@hotmail.com