کتابخانه مقایسه کننده XML در #C

این یک کتابخانه کوچک است که ما آن را برای کمک به نوشتن utility هایی که شامل مقایسه فایل های XML می باشد، توسعه داده ایم. در اینجا می خواهیم کد را برای یک بار به صورت open source بنویسیم و در آینده از آن در برنامه ها استفاده کنیم.

کتابخانه مقایسه کننده XML در #C

پیش زمینه

ممکن است در گذشته  یک utility برای مقایسه/ تبدیل/تولید مستندات از فایل های پیکر بندی که فایل های app.config بودند نوشته اید.(برای مثال XML). وقتی ما شروع به پیاده سازی برخی مرتب سازی ها بر اساس XML comparer در هر بار کردیم، نمی توانستیم این کد را به خاطر برخی سیاست های کارفرمایان publish کنیم.

با بررسی های لازم می بینیم که نزدیکترین کتابخانه به انتخاب ما  کتابخانه های Diff و Patch از مایکروسافت می باشد اما اشکال آنها این است که در نمونه اول، فایل های XML شکست می خورد.

استفاده از کد:

کد حاضر در بخش زیر به طور کامل در ضمیمه همراه با این مقاله آورده شده است.

استفاده از کد بسیار ساده و به صورت زیر است:

public interface IXmlCompareHandler
{
    void ElementAdded(ElementAddedEventArgs e);
    void ElementRemoved(ElementRemovedEventArgs e);
    void ElementChanged(ElementChangedEventArgs e);
    void AttributeAdded(AttributeAddedEventArgs e);
    void AttributeRemoved(AttributeRemovedEventArgs e);
    void AttributeChanged(AttributeChangedEventArgs e);
}

پیاده سازی واسط IXmlCompareHandler (تعریف شده در کتابخانه)

این واسط(Interface) به صورت زیر تعریف می شود:

یک نمونه برنامه کنسول گنجانده شده در git repository نشان داده شده است، و می بینید که چقدر ساده است.

class Program
{
        static void Main(string[] args)
        {
            try
            {
                var file1 = @".\TestFiles\a1.config";
                var file2 = @".\TestFiles\a2.config";
                var handler = new TestXmlCompareHandler();
                using (var comparer = new Comparer(handler))
                {
                    comparer.Compare(file1, file2, handler);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: " + ex);
            }
            Console.Write("Press RETURN to close...");
            Console.ReadLine();
        }
}

کد زیر از برنامه کنسول مشابه گرفته شده است:

فایل های نمونه که در مثال بالا استفاده شده است نیز git repository در github هستند. نسخه اقتباس شده از این فایل ها در زیر نشان داده شده است:

فایل 1:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="initialdatafile" value="db-import.xml"/>
    <add key="migratedatafile" value="db-migrate2.xml" />
  </appSettings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
  </startup>
</configuration>

فایل 2:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="initialdatafile" value="db-import.xml" />
    <add key="migratedatafile" value="db-migrate.xml" />
  </appSettings>
</configuration> 

نتیجه برنامه کنسول در حال اجرا به صورت زیر است:

<>A: /configuration/appSettings/add[@key="migratedatafile"]/@value
     o: 5       : db-migrate2.xml
     n: 5       : db-migrate.xml

-E: 7      : /configuration/startup
             : <startup>   <supportedRuntime version="v4.0" 
             sku=".NETFramework,Version=v4.5.1" /> </startup>

همانطور که می بینید، این خروجی تفاوت در attribute ها را که با "<>A" مشخص شده است، نشان می دهد. همچنین نشان می دهد که یک المان حذف شده است( با "--E" مشخص شده است). توجه کنید که این خروجی توسط TestXmlCompareHandler (کلاسی که واسط IXmlCompareHandler پیاده سازی کرده است) ایجاد شده است.

پیاده سازی شما از IXmlCompareHandler می تواند هر چیزی که شما می خواهید را انجام دهد. بخشی از کد خروجی  به صورت زیر است:

public void ElementChanged(ElementChangedEventArgs e)
{
    Console.WriteLine("<>E: {0}", e.XPath);
    Console.WriteLine("  o: {0,-8}:
    {1}", e.LeftLineNumber, e.LeftElement.Value);
    Console.WriteLine("  n: {0,-8}:
    {1}", e.RightLineNumber, e.RightElement.Value);
    Console.WriteLine();
}

خلاصه

فایل های کلاس مقایسه کننده مانند اسناد XML رفتار می کنند و مثل فایل های متنی نیستند. بنابراین ترتیب المانها مهم نیست.

علاوه بر این کلاس "Patcher" که می تواند برای تبدیل فایل های XML توسط poke کردن مقادیر المان ها/صفت ها و یا حتی تمام المان ها مورد استفاده قرار می گیرد.

NuGet packages را ایجاد کنید.

آموزش سی شارپ

فایل های ضمیمه
دانلود نسخه ی PDF این مطلب