ایجاد یک سند XML با استفاده از LINQ to XML

اگر با کلاس‌های XML DOM برای ایجاد اسناد XML کار کرده باشید، به شما پیشنهاد می‌کنیم از کلاس‌هایی که در فضای نامی System.Xml.Linq قرار دارند استفاده کنید که کار با عناصر XML را بسیار راحت‌تر می‌کنند. ابتدایی‌ترین روش برای بارگذاری یک سند XML استفاده از کلاس XmlDocument می‌باشد که در فضای نامی System.Xml قرار دارد :

XmlDocument doc = XmlDocument.Load("myXmlFile.xml");

به جای کلاس بالا می‌توان از کلاس جدیدتری با نام XDocument نیز استفاده کرد:

XDocument doc = XDocument.Load("myXmlFile.xml");

این کلاس جدید که دارای نام کوتاهتری نسبت به نسخه قدیمی‌تر است چه کاری انجام می‌دهد؟ جواب ساختار وظیفه‌ای است. با ساختار وظیفه‌ای لازم نیست که عناصر XML DOM را یک به یک تعریف کنید. شما می‌توانید با استفاده از سربارگذاری های کلاس X هر کاری که دوست دارید انجام دهید. برای روشن شدن موضوع به مثال زیر توجه کنید. با استفاده از کلاس‌های قدیمی XML DOM موجود در فضای نام System.Xml یک فایل XML ساده ایجاد می‌کنیم :

//A new XML Document
XmlDocument doc = new XmlDocument();
            
//Xml Declaration
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");
//Attach declaration to the document
doc.AppendChild(declaration);

//Create a comment
XmlComment comment = doc.CreateComment("This is a comment");
//Attach comment to the document
doc.AppendChild(comment);
            
//Create root element
XmlElement root = doc.CreateElement("Persons");
//Attach the root node to the document
doc.AppendChild(root);
            
//Create a Person child element
XmlElement person1 = doc.CreateElement("Person");
//Add an attribute name with value John Smith
person1.SetAttribute("name", "John Smith");
//Crate Age element 
XmlElement person1Age = doc.CreateElement("Age");
person1Age.InnerText = "30";
//Create Gender element
XmlElement person1Gender = doc.CreateElement("Gender");
person1Gender.InnerText = "Male";

//Attach Age and Gender element to the Person element
person1.AppendChild(person1Age);
person1.AppendChild(person1Gender);

//Attach Person child element to the root Persons element
doc.DocumentElement.AppendChild(person1);

//Create another Person child element
XmlElement person2 = doc.CreateElement("Person");
//Add attribute name with value Mike Folley
person2.SetAttribute("name", "Mike Folley");
//Crate Age element 
XmlElement person2Age = doc.CreateElement("Age");
person2Age.InnerText = "25";
//Create Gender element
XmlElement person2Gender = doc.CreateElement("Gender");
person2Gender.InnerText = "Male";

//Attach Age and Gender element to the Person element
person2.AppendChild(person2Age);
person2.AppendChild(person2Gender);

//Attach second Person child element to the root Persons element
doc.DocumentElement.AppendChild(person2);

//Save the constructed XML into an XML file
doc.Save(@"C:\sample1.xml");

کد بالا، فایل XML زیر را به وجود می‌آورد :

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--This is a comment-->
<Persons>
   <Person name="John Smith">
      <Age>30</Age>
      <Gender>Male</Gender>
   </Person>
   <Person name="Mike Folley">
      <Age>25</Age>
      <Gender>Male</Gender>
   </Person>
</Persons>

حال همین فایل XML را با استفاده از کلاس‌های جدید LINQ to XML ایجاد می‌کنیم :

XDocument doc = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XComment("This is a comment"),
    new XElement("Persons",
        new XElement("Person", new XAttribute("name", "John Smith"),
            new XElement("Age", new XText("30")),
            new XElement("Gender", new XText("Male"))),
        new XElement("Person", new XAttribute("name", "Mike Folley"),
            new XElement("Age", new XText("25")),
            new XElement("Gender", new XText("Male")))));

doc.Save(@"C:\sample2.xml");

همانطور که مشاهده می‌کنید، هنگام استفاده از کلاس‌های XML DOM برای ایجاد یک سند XML لازم است که شما تک تک عناصر را تعریف کنید. اما با استفاده از کلاس‌های LINQ to XML هر قسمت از سند را در داخل سازنده هر کلاس ایجاد می‌کنید. این روش ایجاد سند XML به ساختار وظیفه‌ای معروف است. هر سربارگذاری کلاس LINQ to XML آرگومان‌هایی قبول می‌کند که همان عناصر فرزند یا مقادیری می‌باشد که قرار است به عنصر اختصاص داده شوند. به عنوان مثال یکی از سربارگذاری های سازنده کلاس XElement به صورت زیراست :

XElement(XName name, params object[] content)

اولین آرگومان نام عنصر است که در قالب یک رشته به سازنده ارسال می‌شود و به صورت خودکار به یک نمونه XName تبدیل می‌شود. دومین پارامتر هم کمی خاص است چون به شما اجازه می‌دهد که هر تعداد از انواع مختلف شئ مانند XText ،XAttribute و یا XElement را به عنصر فرزند از عنصر جاری XElement ارسال کنید. کلاس دیگر LINQ to XML فقط یک آرگومان مانند XComment و XText قبول می‌کند که هر دو یک آرکومان رشته‌ای که نماینده یک متن است را تحویل می‌دهند. در جدول زیر برخی از کلاس‌های LINQ to XML که هر کدام برای ساخت بخش‌های مختلف یک سند به کار می‌روند ذکر شده‌اند :

کلاس توضیح
XDocument نماینده یک سند XML
XDeclaration نماینده یک تعریف در XML
XElement نماینده یک عنصر در XML
XAttribute نماینده صفت یک عنصر در XML
XComment نماینده یک توضیح
XText نماینده متن داخلی یک عنصر XML

به عنوان مثال، اگر بخواهید یک عنصر با نام Person و صفت و مقدار John Smith ایجاد کنید می‌توانید از کد زیر استفاده نمایید :

var personElement = new XElement("Person", new XAttribute("name", "John Smith"));

برای اضافه کردن یک عنصر فرزند به عنصر فوق هم می‌توان به راحتی یک آرگومان به سازنده XElement اضافه کرد :

var personElement = new XElement("Person", new XAttribute("name", "John Smith"), 
                        new XElement("Age", new XText("30")));

عنصر فرزند دارای خصوصیت Age (سن) است که با استفاده از آرگومان بعدی در سازنده متن داخلی آن را با استفاده از کلاس XText تعیین می‌کنیم. در مثال 2 مشاهده می‌کنید که هر آرگومان XElement دارای تورفتگی می‌باشد که شبیه به تورفتگی عناصر XML می‌باشد. در آخر مثال 2 متد ()XDocument.Save را فراخوانی کرده‌ایم که به شما اجازه می‌دهد ساختار XML را در حافظه ذخیره کنید. این متد یک رشته را به عنوان آرگومان قبول می‌کند که همان مسیر فایل می‌باشد. اگر فایل وجود نداشته باشد آن را ایجاد و اگر وجود داشته باشد آن را بازنویسی (overwritte) می‌کند. این متد دارای سربارگذاری های دیگری هم می‌باشد که ما از یکی از آنها برای ذخیره فایل XML استفاده کردیم.