مدتها بود که به دنبال فرصت مناسبی برای یادگیری بعضی اصطلاحات Xml و معنی آنها میگشتم. از آنجا که اصطلاحات به کار رفته در Xml تنوع خیلی زیاد و معانی شبیه به هم دارند، روال یادگیری نسبتاً سختی هم دارند. طی مدت اخیر برای این که پروتکل ECE را بیشتر بفهمم و بعضی مسائل آن مثل اجباری یا اختیاری بودن xmlns و یا بحث validation را بهتر بفهمم مجبور شدم این فرصت مطالعاتی را اجباراً برای خودم مهیا کنم! با این که نتیجه این مطالعه تقریبا شبیه بیشتر Glossaryهای رایج مثل این است ولی من سعی کردهام آنهایی را که فعلا بیشتر نیاز دارم یا برایم مبهمتر هستند و خصوصا آنهایی که در بحث پروتکل ECE کاربرد بیشتری دارند را در اینجا بیاورم. مثالها هم به دلیل اهمیت پروتکل ECE بر اساس نمونه Xml زیر که خود یک نامه بر اساس پروتکل ECE است، آورده شدهاند:
<?xml version="1.0" encoding="utf-8"?>
<Letter
xmlns="http://www.irica.com/ECE/1383-12/SendSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Protocol Name="ECE" Version="1.01" />
<Software
SoftwareDeveloper="http://afsharm.blogspot.com/"
Version="1.0.0.0"
GUID="A9032C8A-B4E9-4c06-8CA2-04D440547FAF" />
<Sender Organization="متروی تهران"
Department="نیروی انسانی"
Position="جانشین"
Name="حسین فرمند"
Code="765" />
<Receiver Organization="شهرداری اصفهان"
Department="طرح و توسعه"
Position="معاون"
Name="فرخ پاینده"
Code="174"
ReceiverType="Origin" />
<OtherReceivers />
<LetterNo>649</LetterNo>
<LetterDateTime
ShowAs="gregorian">
2008-01-15T14:43:46
</LetterDateTime>
<RelatedLetters />
<Subject>عید نوروز باستانی</Subject>
<Priority Code="0" Name="Normal" />
<Classification Code="0" Name="Normal" />
<Keywords>
<Keyword>تبریک</Keyword>
<Keyword>جدید</Keyword>
<Keyword>کارمند</Keyword>
</Keywords>
<Origins />
<Attachments />
</Letter>
در ادامه هر یک از مفاهیمی که برایم مهم بوده در حد امکان توضیح داده شده است. دو مفهوم namespace و XPath به دلیل اهمیت خیلی زیادی که برای خودم و پروتکل ECE داشت به طور کامل توضیح داده شدهاند:
- Markup: راهی برای معرفی شکل و شمایل یک متن. مثلا HTML یک Markup است که روش نمایش متون را در مرورگرها نمایش میدهد. برخلاف تصور عموم، Xml یک نوع Markup نیست بلکه ابزاری برای تعریف Markup است. Markupهایی مثل MathML یا همین پروتکل ECE خودمان. گاها به Markup، زبان یا language هم گفته میشود، مثلا به HTML، زبان HTML هم گفته میشود.
- XML: مجموعهای از قوانین و مقررات است که با استفاده از آن یک Markup یا زبان جدید تشریح میشود. یک فایل Xml متشکل است از مجموعهای از elementها، tagها، nodeها و… Xml یک نسخه ساده شدهی SGML و خود SGML یک ساختار قدیمی و خیلی پیچیده برای انتقال اطلاعات است. بسیاری از فایلهای امروزی ساختار Xml دارند. Xml خیلی از ساختارهای قدیمی از جمله CSV را از میدان رقابت به در کرده است.
- Tag: به متنی که بین دو علامت کوچکتر و بزرگتر قرار دارد به علاوه خود علامتها گفته میشود. مثل <Sender> و </Keywords>. معنی tag خیلی کوچکتر و سادهتر از element است.
- Content: به هر گونه متنی که بین دو tag قرار دارد گفته میشود. مثل عبارت «عید نوروز باستانی» که در داخل تگ Subject قرار دارد.
- Element: مجموعه کامل tag و content آن را element میگویند. مثل <LetterNo>649</LetterNo> و <Origins />. هر element میتواند شامل elementهای دیگری باشد. این تو در تو بودن elementها میتواند تا هر اندازهای که لازم باشد تکرار شود. elementها نمیتوانند همپوشانی داشته باشند. یعنی تگ آغاز و پایان هر element باید به طور کامل بین تگ آغاز و پایان element والد خود باشد. به طور مثال تکه Xml زیر اشتباه میباشد:
<a>here<b>there</a>bye</b>
- Attribute: یعنی اطلاعاتی که به صورت جفتهای مقدار/داده در داخل tag به منظور توضیح رفتار آن element قرار میگیرد. مثل Code و Name در عنصر <Priority>.
- Node: به هر کدام از مفاهیم tag، element و attribute یک Node گفته میشود.
- Root Element: به elementی که دربرگیرنده همه elementهای یک سند xml است گفته میشود. هر سند xml فقط و فقط یک root element دارد نه کمتر نه بیشتر.
- CDATA: راهی است برای وارد کردن Contentهای طولانی که شامل کاراکترهای خاصی هستند.مثلا شما هیچ وقت نمیتوانید در content یک element علامت «کوچکتر از» یعنی "<" را وارد کنید بلکه به جای آن باید از < استفاده شود. در بعضی حالات خاص اگر قرار باشد متنی که پر از علامتها و کاراکترهای خاص هستند وارد شود دردسر زیادی به وجود خواهد آمد. ضمن آن که خوانایی متن هم کاهش مییابد. به عنوان نمونه به مثال زیر دقت کنید:
<Subject>
<![CDATA[if (a>b && c<d) e++;]]>
</Subject>
- White Space: به مجموعه کاراکترهای فاصله (0x20)، Tab(0x09)، LF (0x0A) و CR(0x0D) گفته میشود. از ۲ تای آخر در سیستم عاملهای مختلف به عنوان جدا کننده خطوط در سیستم فایل استفاده میشود. Xml Processorهای مختلف در شرایط مختلف، برخوردهای متفاوتی با white spaceها دارند. مثلا بین هر دو attribute هر تعداد هم white space وجود داشته باشد مشکلی در ساختار xml به وجود نمیآید. این یعنی هر attribute را میتوان در یک خط جداگانه تعریف کرد. در نقطه مقابل، white spaceهای موجود در content یک element حفظ شده و در نظر گرفته میشوند. این یعنی اگر content یک element از چندین خط نوشته تشکیل شده بود در content مربوطه کلیه کاراکترهای CR/LF هم ذخیره شده و در نمایشهای بعدی (مثلا درج اطلاعات xml در یک دیتابیس) هم نمایش داده خواهند شد.
- DTD: راهی است برای کشف این نکته که آیا یک سند xml خاص مطابق با یک زبان یا markup خاص هست یا نه. این اعتبار سنجی از منظر واژگان (Vocabulary) و ساختار (Grammar) بررسی میشود. DTD رقیبی به نام Xml Schema دارد. DTD از Schema خیلی قدیمیتر و تقریبا همانی است که برای اعتبار سنجی اسناد SGML استفاده میشده در حالی که Xml Schema جدیدتر، راحتتر و رایجتر است.
- Xml Schema: راهی است برای اعتبار سنجی یک سند Xml. این اعتبار سنجی از دو دیدگاه واژگان (Vocabulary) و ساختار (Grammar) انجام میشود. Xml Schema رقیبی جدی و در خیلی از موارد جایگزینی برای DTD محسوب میشود.
- Namespace: هر سند xml شامل یک سری tag و attribute است به علاوه یک ساختار کلی که نشان میدهد اجزای آن چطوری با هم ارتباط دارند. این اجزا را Vocabulary و ساختار آنها را Grammar مینامند. به مجموعهای از vocabularyهای مرتبط با هم که یک زبان یا markup مشخص را تعریف میکنند namespace گفته میشود. مثلا کلمات نامه، ساختار، نمایش، نوشته، استفاده، رفتار و… بخشی از vocabulary زبان فارسی و در نتیجه عضو namespace زبان فارسی هستند. Namespaceها فقط vocabulary یک زبان را مشخص میکنند و کاری به grammar آن ندارند. به عنوان مثال تمکیلی به مجموعه Letter، Software، Version، Organization، Code و OtherReceivers هم به عنوان بخشی از vocabulary پروتکل ECE دقت فرمایید. این مجموعه متعلق به namespace پروتکل ECE هستند.
namespaceها به صورت یک attribute تعریف میشوند. ns (مختصر شده namespace) را هم میتوان با نام و هم بدون نام تعریف کرد. مثال:
در مثال بالا تگ Letter به عنوان عضوی از ns مربوطه تعریف شده و کلیه elementهای زیرمجموعه آن و attributeها و تگها آنها هم در صورتی که صراحتا عضو ns دیگری اعلام نشده باشند، عضوی از این ns خواهند بود. در روش بینام نیازی به استفاده از prefix در ابتدای نام tagها یا attributeها نیست. در هر تگ فقط یک ns بینام را میتوان تعریف نمود.
در تعریف ns با نام باید از ساختار زیر تبعیت کرد:
<Letter
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
یعنی اول عبارت xmlns: آمده و سپس یک prefix برای ns مورد نظر تعریف میشود مثل xsi یا xsd. بعد از آن هم یک علامت مساوی و سپس رشته معرفی کننده ns در داخل دابل کوتیشن میآید. رشته معرفی کننده چه در حالت بینام و چه در حالت با نام هیچ معنی خاصی نداشته و میتواند هر چیزی باشد مثل نام یک شهر، شماره ملی یک شخص و یا یک عدد ۴ رقمی. تنها قاعدهای که باید رعایت شود این است که این رشته باید در محدوده nsهای استفاده شده در یک xml منحصر به فرد باشد. طراحان یک Xml معمولا یک آدرس اینترنتی (URL) را برای این رشته استفاده میکنند. بیشتر وقتها چنین آدرسی اصلا وجود ندارد و صرفا نمایانگر نام شرکت یا موسسه، تاریخ و نسخه ns مورد نظر است. ولی بهتر است برای مطالعه احتمالی افراد در همان آدرس مشخصات و تعاریف ساختار xml مورد نظر قرار داده شود.
در صورتی که مثل مورد زیر یک تگ با ns بدون اسم تعریف شود، تمام elementهای زیرمجموعه آن هم خود به خود عضو ns آن میشوند مگر آنکه صراحتا خلاف آن خواسته شده باشد. در این روش نیازی به استفاده از prefix نیست.
<Letter
xmlns="http://www.irica.com/ECE/1383-12/SendSchema">
<Protocol Name="ECE" Version="1.01" />
</Letter>
در صورتی که از ns با اسم استفاده شود باید قبل از attributeها و تگها، prefix مربوطه اضافه شوند. مثل:
<?xml version="1.0" encoding="utf-8"?>
<Letter
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsi:a1/>
<xsd:a2 xsd:t1="somtehing"/>
<a3></a3>
</Letter>
در این مثال elementهای <Letter> و <a3> عضو هیچ nsی نیستند در حالی که a1 عضو xsi و a2 و t1 هم عضو xsd هستند.
- XPath: یک زبان برای استخراج اطلاعات از یک ساختار Xml است. رابطه XPath با Xml مثل رابطه SQL با دیتابیس است. به عنوان مثالی از XPath، برای استخراج موضوع (Subject) نامه از یک Xml پروتکل ECE در صورتی که از هیچ ns استفاده نشده باشد از XPath زیر استفاده میشود:
و این XPath اگر از ns مربوط به پروتکل ECE (Send) یعنی "http://www.irica.com/ECE/1383-12/SendSchema" استفاده شود به شکل زیر در میآید:
در مثال دوم فرض شده است که ns مربوطه بدون نام تعریف شده و ضمنا پیشوند ltr پیشوندی است که در داخل کد برنامه به آن اختصاص داده شده نه در تعریف ns یعنی:
<?xml version="1.0" encoding="utf-8"?>
<Letter
xmlns="http://www.irica.com/ECE/1383-12/SendSchema">
<Subject>دبیرخانه</Subject>
</Letter>
البته اگر xml به صورت زیر تعریف شده بود:
<?xml version="1.0" encoding="utf-8"?>
<Letter
xmlns:ltr="http://www.irica.com/ECE/1383-12/SendSchema">
<Subject>دبیرخانه</Subject>
</Letter>
آنگاه Xpath دوم بدون خروجی خواهد شد. چون در این حالت ns مربوطه همراه با پیشوند ltr تعریف شده بود در حالی که نه تگ Letter و نه تگ Subject هیچ کدام از این پیشوند استفاده نکردهاند. اگر قرار باشد از XPath دوم استفاده شده و خروجی دریافت گردد باید Xml فوق را به شکل زیر عوض کرد:
<?xml version="1.0" encoding="utf-8"?>
<ltr:Letter
xmlns:ltr="http://www.irica.com/ECE/1383-12/SendSchema">
<ltr:Subject>دبیرخانه</ltr:Subject>
</ltr:Letter>
ذکر این نکته خیلی خیلی ضروری است که اگر در یک xml یک سری ns با نام (یعنی دارای پیشوند) تعریف شده ولی هیچ کدام از تگها یا attributeها از استفاده نکرده باشند، میتوان آن nsها را پاک کرد بدون آن که هیچ اختلالی در عملکرد xml مربوطه به وجود بیاید. مثلا در نمونه پروتکل ECE که در ابتدای متن آمده است، namespaceهای xsi و xsd کاملا روی اجزای xml داده شده بیتاثیر هستند و میتوان آنها را محض خوانایی بیشتر از xml حذف کرد.
—————————-
نکته تکمیلی ۱: هر آنچه که در Xml موجود است از جمله تگها و attributeها، به کوچکی و بزرگی حروف حساس (Case Sensitive) هستند.
نکته تکمیلی ۲: اگر encoding خط اول هر xml برابر utf-8 تعریف شده باشد (که در بیشتر مواقع همین طور است)، آنگاه استفاده از هر نوع کاراکتر فارسی و غیر فارسی در Contentها و مقادیر داخل دابل کوتیشن attributeها مجاز است.
نکته تکمیلی ۳: برای مطالعه تکمیلی به این مفاهیم توجه کنید: XSLT, XSD, Base64, URI, URL, URN, Well-formed Xml
نکته تکمیلی ۴: این نوشته بر اساس کتاب Learning XML, Erik T. Ray نوشته شده است.
مراجع:
Comments
رفته رفته مطالب این وبلاگ را بیشر از قبل می پسندم. موفق باشید
در مورد xmlns ها این قدر توضیح دادی که واقعا هر چیزی از قبل هم در این مورد می دانستم با این موارد شبهه بیشتری را برای من ایجاد کرد!!! گرچه مطالب اینجا بیش از آنچیزی بود که می دانستم.
سپاسگزارم جناب حاجلو!
پیشنهاد می کنم یک برنامه که در بر گیرنده کلیه مطالب فوق باشد را به زبان vb.net یا #c به نوشته فوق ضمیمه کنید.
امیدورام یک روز وقت چنین کاری را پیدا کنم.
خیلی ممنون ، مختصر و مفید
~~>موفق باشید<~~
so thanks….