آموزش کار با فایل XML در زبان C#

XML مخفف عبارت Exteraible Markup Language یا زبان نشانه گذاری قابل توسعه است. زبان XML ، یک فرمت گسترده و رایج برای نقل و انتقال اطلاعات (data) می باشد، بیشتر به این دلیل که به راحتی برای هم انسان و هم ماشین قابل خواندن و درک است.
اگر تاکنون سایتی را به زبان HTML نوشته باشید، XML بسیار برای شما آشنا به نظر خواهد آمد، زیرا درواقع XML یک نسخه سخت گیرانه تر و توسعه داده شده تر از HTML است. XML از تگ ها (tags)، خصوصیات (attributer) و مقادیر (values) تشکیل شده و ساختار کلی کدهای آن، همانند کد مثال زیر است :

<users>
  <user name="John Doe" age="42">
  <user name="Jane Doe" age="39">
</user></user>
</users>

همانطور که در کد مثال فوق می توانید مشاهده کنید، XML یک فرمت مناسب برای تعریف اطلاعات یا data بوده و اکثر زبان های برنامه نویسی دارای کلاس ها و توابع خاصی برای کار با XML هستند. زبان C# هم یکی از این زبان های برنامه نویسی است که یک فضای کلاس مخصوص یا namespace، برای کار با XML دارد. نام این namespace در زبان C#، مجموعه System .XML است که تقریبا توانایی کار با قابلیت های مختلف زبان XML را داراست.

 کلاس XMLReader

به طور کلی ۲ متد برای خواندن فایل های XML در زبان C# وجود دارد :

کلاس xmlDocument .
کلاس XMLReader .
کلاس XMLDocument کل محتویات فایل XML را خوانده و در حافظه سیستم قرار می دهد. سپس به شما امکان می دهد به راحتی درون فایل XML به جلو و عقب حرکت کرده و حتی با استفاده از تکنولوژی XPath ، جستجو یا query مورد نظر خود را بر روی فایل انجام دهید.
کلاس XMLReader، گزینه ای سریع تر و کمتر حافظه بر (memory consuming) بر خواندن فایل های XML می باشد. کلاس XMLReader به شما امکان می دهد تا در هر لحظه به وسیله فقط یک المنت، درون محتویات فایل XML حرکت کرده و همزمان مقدار value ها را خوانده و سپس به المنت بعدی در فایل بروید. با انجام اعمال فوق، بدیهی است که برنامه حافظه بسیار کمتری را اشغال می کند، زیرا در هر لحظه فقط مقدار المنت جاری را در خود نگهداری خواهد کرد. علاوه بر این، به دلیل این که می توانید به صورت دستی مقدار هر value را چک کنید، مستقیما به مقادیر مورد نظر خود دسترسی خواهید داشت و این مسئله کار را بسیار سریع تر می کند.
در این درس، بر روی کار با کلاس XMLReader تمرکز کرده و در درس بعدی به آموزش کلاس XMLDocument Class خواهیم پرداخت.
برای آموزش عملی مباحث، بیایید با یک مثال کوچک کار کنیم که در آن یک فایل XML حاوی نرخ های ارز (currency rates) را خواهیم خواند. برای این منظور از یک فایل XML مربوط به بانک مرکزی اروپا استفاده می کنیم. می توانید این فایل را دانلود کرده و از روی هارد دیسک بخوانید. اما درواقع هر دو کلاس XMLReader و کلاس XMLDocument می توانند به خوبی، محتویات یک فایل XML را از روی یک آدرس Url بر روی یک سرور را ه دور همانند فایل های لوکال بخوانند و فایل XML مثال را می توانید از آدرس + آدرس مشاهده نمایید، در کد مثال زیر، بخشی از این فایل را استفاده خواهیم کرد :

using System;
using System.Text;
using System.Xml;
 
namespace ParsingXml
{
    class Program
    {
        static void Main(string[] args)
        {            
            XmlReader xmlReader = XmlReader.Create("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml");
            while(xmlReader.Read())
            {
                if((xmlReader.NodeType == XmlNodeType.Element) && (xmlReader.Name == "Cube"))
                {
                    if(xmlReader.HasAttributes)
                        Console.WriteLine(xmlReader.GetAttribute("currency") + ": " + xmlReader.GetAttribute("rate"));                    
                }
            }
            Console.ReadKey();
        }
    }
}

در ابتدای کار یک نسخه جدید از کلاس XMLReader Class را با استفاده از متد Create() ایجاد کرده ایم. این متد چندین overload (مجموعه پارامتر) را می تواند دریافت کند، اما ساده ترین حالت آن ارسال یک Url با آدرس فایل XML مورد نظر برای خواندن است. درون حلقهwhile loop، متد Read() را بر روی نسخه ایجاد شده از کلاس XMLReader فراخوانی می کنیم. این حلقه، خواننده فایل یا Reader را به المنت بعدی در فایل منتقل کرده و در صورت وجود داشتن المنت ی دیگر، مقدار true را بر می گرداند تا عملیات جستجو همچنان ادامه داشته باشد. با تمام المنت های فایل و صدور مقدار false، اجرای حلقه و خواندن فایل متوقف خواهد شد. در درون حلقه while loop می توانید از خواص (properties) و متدهای (methods) متنوع کلاس XMLReader برای دسترسی به اطلاعات المنت جاری یا مورد نظر خود استفاده کنید.
در مثال فوق، ابتدا خاصیت NodeType را چک کرده تا مطمئن شده فایل دارای المنت (قسمت tag) بوده و همچنین آیا نام آن برابر با “Cub” است یا خیر. همانطور که در فایل XML مثال می توانید ببینید، هر نرخ ارز (currency rate) دارای یک المنت با نام تگ Cube می باشد و این دقیقا چیزی است که ما به دنبال آنیم. به محض پیدا کردن یک المنت Cube، یک چک فرمت (format check) انجام داده تا ببینیم آیا المنت ما دارای خواص (attributes) یوده و یا خیر و سپس توسط متد Get Attribute() مقدار دو خاصیت “currency” و “rate” را می خوانیم. در نهایت مقادیر دو خاصیت را در خروجی چاپ کرده و به سراغ المنت بعدی می رویم. خروجی کد مثال فوق، بایستی لیستی از Currency های موجود و نرخ آن ها (rate) باشد.
همانطور که مشاهده کردید روند کار بسبار ساده بود. البته این بیشتر به دلیل این است که ما اطلاعات را به همان ترتیبی که خواندیم، نیاز داشتیم، بدون این که عملیات خاصی بر روی آن ها انجام دهیم. به عبارت دیگر، وقتی لیستی از داده ها را به صورت لیست ترتیبی نمایش دادیم

کلاس XMLDocument حافظه بیشتری از کلاس XMLReader مصرف کرده و به طبع کند تر از آن می باشد. اما به هر حال، به چند دلیل، کار با کلاس XMLDocument کمی ساده تر بوده و در برخی موارد نیاز به نوشتن کد کمتری خواهد داشت.
به محض این که محتویات فایل XML را خواندید، می توانید اطلاعات درون آن را به روش درختی (hierarchical) مورد ارزیابی قرار دهید، دقیقا همانند ساختار فایل های XML که در آن هر المنت دارای چندین عنصر فرزند یا child بوده و هر child نیز می تواند چندین عنصر فرزند داشته باشد و به همین ترتیب.
در درس قبلی، اطلاعات را از یک فایل XML مربوط به بانک مرکزی اروپا خواندیم که درباره نرخ های ارز و تغییرات آن ها داده هایی را ارائه می دهد. در این درس هم به انجام این کار خواهیم پرداخت، اما با استفاده از کلاس XMLDocument به جای XMLReader.
اطلاعات فایل XML را می توانید از آدرس +آ درس دریافت نموده و داده ای که در آن نیاز داریم، در عنصر قرار داد. ساختار درختی فایل XML مثال، چیزی همانند کد زیر است :

< gesmes:Envelope >
    [other child nodes]
    < Cube >
        < Cube time="2011-04-12" >
            < Cube currency="USD" rate="1.4470"/ >
            < Cube currency="JPY" rate="121.87"/ >
            …

المنت ، المنت اصلی یا root element فایل است، که می توان توسط خاصیت DocumentElement به آن دسترسی داشت.
در مرحله بعدی، می توانیم با استفاده از خاصیت ChildNodes Collection به عنصرهای فرزند المنت اصلی دسترسی پیدا کنیم. در مثال این درس، قصد داریم تا به عنصرهای فرزند یا child در سه رده یا level زیر المنت اصلی دسترسی پیدا کنیم. این کار را با استفاده از کد مثال عملی زیر می توان انجام داد، دقیقا مشابه کاری که در درس قبل با کلاس XMLReader انجام دادیم :

using System;
using System.Text;
using System.Xml;
 
namespace ParsingXml
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("www.ecb.int/stats/eurofxref/eurofxref-daily.xml");
            foreach(XmlNode xmlNode in xmlDoc.DocumentElement.ChildNodes[2].ChildNodes[0].ChildNodes)
                Console.WriteLine(xmlNode.Attributes["currency"].Value + ": " + xmlNode.Attributes["rate"].Value);
            Console.ReadKey();
        }
    }
}

همانطور که در کد مثال مشاهده می کنید، ما به عنصر Cube nodes با پایین تر رفتن از ساختار درختی ChildNodes hierarchy دسترسی پیدا کرده ایم. از المنت اصلی فایل که DocumentElement نام دارد، سراغ المنت سوم فرزند child node (دارای اندیس بر پایه صفر) را گرفته ایم. سپس به دنبال اولین فرزند این المنت یا first child node گشته و در نهایت کلیه عناصر فرزند این عنصر یا Collection of child nodes را درخواست کرده ایم.
بدیهی است کد فوق به دلیل این که ما با ساختار فایل XML مثال آشنا هستیم، کاربرد داشته و برای مراحل بعدی در آینده چندان انعطاف پذیر و مناسب نیست.
به هر حال روشی که شما برای پیدایش یک فایل XML به کار خواهید برد، بستگی زیادی به سورس فایل XML و نوع اطلاعاتی که دنبال آن هستید، دارد.
کد مثال این درس، تنها در صورتی که حجم محدودی از اطلاعات داشته باشیم، کار خواهد کرد اما برای اهداف بزرگ تر، نیازمند نوشتن کد بهتری هستیم تا خوانایی برنامه افزایش پیدا کند.
به دلیل این که ما دارای یک گره یا node به نام Currency rate هستیم و می توانیم به دو خاصیت یا properties آن دسترسی داشته و آن را در خروجی چاپ کنیم، کد فوق مثال خوبی است

شاید این مطالب را هم دوست داشته باشید

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.