سندرم شماره نامه به هم ریخته

همه کسانی که در نوشتن نرم‌افزارهای دبیرخانه دخیل بوده‌اند با مشکلی به اسم به هم ریختگی شماره نامه آشنا هستند. شماره نامه معمولاً ترکیبی از اعداد، علائم، حروف فارسی و گاهاً انگلیسی هستند. از آنجا که ما در یک محیط دو جهته زندگی می‌کنیم هنوز در نحوه چینش صحیح این حروف در کنار یکدیگر ابهاماتی وجود دارد و مردم بسیاری از قواعد موجود را هم یا نمی‌شناسند یا اصلاً به کار نمی‌برند. در نتیجه چیزی که کاربر با هزار دردسر به عنوان شماره نامه وارد می‌کند به هنگام نمایش مجدد دچار به هم ریختگی می‌شود. مثلاً جای حروف و علائم عوض شده یا علامتی مثل خط تیره به جای آن که در سمت راست یک کاراکتر نمایش یابد به سمت چپ آن منتقل می‌شود. این قضیه وقتی تشدید می‌شود که شماره نامه ذخیره شده را بخواهیم در محیط‌های متنوعی مثل reportها، برنامه‌های ویندوزی، وب (IE و فایرفاکس)، xmlهای مربوط به پروتکل ECE و محیط‌های خام مثل SQL Server Management Studio نمایش دهیم. به عنوان نمونه به تصاویر زیر که یک شماره نامه واحد را آن طور که در محیط‌های مختلف دیده می‌شود دقت کنید:

افراد مختلف راه حل‌های مختلفی را برای غلبه بر این مشکل پیدا کرده‌ند. بعضی‌ها یک MaskEdit برای ورود شماره در نظر گرفته‌اند. بعضی‌ها شماره نامه وارده شده را به صورت یک عکس render کرده و نمایش می‌دهند. بعضی‌ها برای نمایش صحیح در صفحات وب یک ActiveX ایجاد کرده‌اند. بعضی‌ها هم قالب شماره نامه را طوری تعریف کرده‌اند که دچار مشکل کمتری شوند و این قالب را به کارفرما تحمیل کرده‌اند.


اما راه حلی که من مورد استفاده قرار داده‌ام استفاده از نویسه یونیکد LEFT-TO-RIGHT OVERRIDE است. وجود این نویسه در هر رشته‌ای باعث می‌شود کلیه نویسه‌هایی که بعد از آن وارد می‌شوند به صورت اکیداً چپ به راست نمایش نمایش یابند. یعنی انگار نه انگار محیط کار، راست به چپ است. به عنوان مثل فرض کنید می‌خواهیم جمله «پاییز زیبا است» را یک بار به صورت عادی و یک بار دیگر هم با وارد کردن این کاراکتر بین کلمات «پاییز» و «زیبا» نمایش دهیم. عکس زیر هر دو حالت را نمایش می‌دهد.

حال روش من برای استفاده از این کاراکتر این است که در رویداد OnKeyPress (یا هر رویداد مشابه دیگری) بعد از ورود هر کاراکتر توسط کاربر، این کاراکتر نیز به قبل از آن اضافه شده سپس نمایش یابد. نهایتاً به هنگام ذخیره متن وارد شده بایستی به جز کاراکتر ابتدای متن، بقیه کاراکترهای LEFT-TO-RIGHT OVERRIDE را از متن پاک کرد. چون وجود بیش از یک مورد آن غیر ضروری است. برای درک بهتر موضوع به کد جاوا اسکریپت زیر که این روش را در صفحات وب پیاده سازی می‌کند دقت کنید. بدیهی است که برای WinForm و WPF هم می‌توان این روش را به کار برد:

function ltr_override(e)
{
//‫از این تابع در onkeypress هر textBox که استفاده شود باعث می‌شود که
//کاراکترهای تایپ شده توسط کاربر به طور مطلق از چپ به راست نمایش داده
//شود. حتی اگر کاربر یک متن فارسی را وارد کند. کاربرد فعلی این تابع
//در شماره نامه است که همیشه از چپ به راست خوانده می‌شود

//‫دقت شود که رشته تولید شده توسط این تابع پر از کاراکتر یونیکد 0x202d است و
//قبل از ذخیره در بانک اطلاعاتی یا انجام هر پردازش دیگری باید از رشته مورد نظر پاک شود

var key;
var obj;
if (window.event) {
e = window.event;
obj = e.srcElement;
key = e.keyCode;
} else {
obj = e.target;
key = e.charCode;
}
//0x202d: LEFT-TO-RIGHT OVERRIDE
obj.value = String.fromCharCode(0x202d)+obj.value;
return true;
}

پ. ن. ۱: کاراکتر LEFT-TO-RIGHT OVERRIDE یکی از کاراکترهای ویژه معرفی شده در الگوریتم شماره ۹ یونیکد (الگوریتم دو جهته) و جزیی از استاندارد ماتصا ۶۲۱۹ (ISIRI 6219) می‌باشد.

پ. ن. ۲: برای مطالعه بیشتر اینجا و اینجا را بخوانید.

پ. ن. ۳: استفاده از ابزارک «فردیس» شاید بتواند در کار با نویسه‌های ویژه یونیکد کمک کند.

پ. ن. ۴: من ایده اصلی این کار را از این کتابخانه که برای شبیه سازی صفحه کلید ۲۹۰۱ در محیط‌های غیر فارسی نوشته شده بود و با نگاهی به اینجا و اینجا گرفتم.

‫‫‫Sequence Diagram در ۷ گام

۱- Sequence Diagram را در فارسی، نمودار توالی می‌گویند.
۲- تقریباً به ازای هر «سناریو» یک نمودار توالی وجود دارد. برای انجام هر «سناریو» چندین آبجکت با همدیگر تعامل دارند.
۳- نمودار توالی برای نشان دادن جزییات الگوریتم اجرای عملیات مثل حلقه و شرط خیلی ضعیف است و بهتر است برای این کار از Activity Diagram استفاده کرد.
۴- برای کشیدن «نمودار توالی» از دو روش رایج به نام‌های centralized control و distributed control استفاده می‌شود. روش «توزیعی» در دنیای شی‌گرا خیلی رایج‌تر است. این روش طراح را تشویق می‌کند به جای یکی دو تا کلاس بزرگ و چند متود خیلی طولانی، از چندین کلاس کوچک و چندین متود خیلی کوتاه استفاده کند.
۵- فراخوانی متود هم به روش هم‌زمان و هم به روش غیرهم‌زمان قابل انجام است. روش غیرهم‌زمان در برنامه‌های Multi Thread کاربرد دارد.
۶- بعضی افراد به جای «نمودار توالی» از CRC که یک ابزار غیر UMLی است به عنوان یک جایگزین استفاده می‌کنند. CRC بسیار مشابه «نمودار توالی» است ولی رسم آن خیلی راحت‌تر و استفاده از آن هم خیلی رایج است.
۷- به عکس زیر به عنوان نمونه‌ای از «نمودار توالی» که در پروتکل ای.سی.ای استفاده می‌شود نگاه کنید.

نمودار توالی

منبع: فصل چهارم کتاب UML Distilled نوشته مارتین فولر

‫نحوه خطایابی عملیات ارسال/دریافت ایمیل

debug یکی از مشکلاتی که همیشه در آزمایش و راهبری پروتکل ECE به وجود می‌آید مشکلات مربوط به ارسال/دریافت ایمیل است. متاسفانه امکانات اولیه کلاس‌ها و کامپوننت‌های این کار اطلاعات چندان کاملی از خطای رخ داده به دست نمی‌دهند و گاها به یک خطای timed out بسنده می‌کنند. به عنوان مثال به خطای زیر که حاصل اجرای عملیات ارسال ایمیل با کلاس SmtpClient است توجه فرمایید:

(SendingMailException): The operation has timed out.,
(SmtpException): The operation has timed out.,

در این جور مواقع می‌توانید کلیه فعالیت‌های System.Net را زیر نظر بگیرید، شاید که مشکل ارسال/دریافت ایمیل را پیدا کردید. دقت کنید که با انجام این کار هر فعالیتی که بر روی TCP/IP انجام گیرد log شده و حجم فایل log در یک چشم به هم زدن به چندین مگابایت خواهد رسید. علاوه بر این پیدا کردن اطلاعات مورد نظر در این حجم زیاد اطلاعات کار چندان ساده‌ای نیست. در ادامه بخشی از این اطلاعات به عنوان نمونه آمده است:

System.Net.Sockets Verbose: 0 : [2616] Socket#23006966::Send()
System.Net.Sockets Verbose: 0 : [2680] Socket#23006966::Dispose()
System.Net.Sockets Error: 0 : [2616] Exception in the Socket#23006966::Send – A blocking operation was interrupted by a call to WSACancelBlockingCall
System.Net.Sockets Verbose: 0 : [2616] Exiting Socket#23006966::Send()     -> 0#0
System.Net Error: 0 : [2616] Exception in the SmtpClient#49662634::Send – Unable to write data to the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall.

حال برای فعال کردن «خطایابی» در برنامه خودتان کافی است کد زیر را به web.config یا app.config خود اضافه کنید. این کد در بالاترین سطح و درست زیر <configuration> اضافه می‌شود. همان جایی که <appSettings> و <system.web> قرار دارند:

<system.diagnostics>
<
trace autoflush="true" />
<
sources>
<
source name="System.Net" >
<
listeners>
<
add name="MyTraceFile"/>
</
listeners>
</
source>
<
source name="System.Net.Sockets">
<
listeners>
<
add name="MyTraceFile"/>
</
listeners>
</
source>
</
sources>
<
sharedListeners>
<
add
name="MyTraceFile"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="d:usersSystem.Net.trace.log"/>
</
sharedListeners>
<
switches>
<
add name="System.Net" value="Verbose" />
<
add name="System.Net.Sockets" value="Verbose" />
</
switches>
</
system.diagnostics>

‫وضعیت Xml Namespace در پروتکل ECE

xml-ns بالاخره بعد از مدت‌ها تکلیفمان با namespace استفاده شده در تگ Letter ایکس‌ام‌ال‌های «ارسال» و «رسید» در پروتکل ECE معلوم شد، البته تقریباً. این namespace که برای «ارسال» برابر است با "http://www.irica.com/ECE/1383-12/SendSchema" و برای «رسید» برابر است با "http://www.irica.com/ECE/1383-12/ReceiptSchema" برای ما و خیلی از پیاده‌سازان دیگر ابهام داشت. به حدی که بعضی‌ها مثل ما مجبور شدند با چند تا از همکارانشان در دیگر شرکت‌ها بر سر بود و نبود این namespaceها به طور داخلی به توافق برسند.

برای حل این مشکل حدود یک ماه پیش با چند نفر از طراحان اصلی پروتکل ECE تماس گرفتم و فهمیدم که قرار است نسخه بعدی پروتکل این ابهام را از بین ببرد. علاوه بر این معلوم شد که بیشتر شرکت‌ها فرض را به اجباری بودن وجود این دو namespace قرار داده‌اند. خود بنده هم پس از دیدن خط targetNamespace="http://www.irica.com/ECE/1383-12/SendSchema" در فایل ‪1.xsd‬‎ که از سایت رسمی پروتکل ECE قابل دریافت است و مطالعه‌ای که روی موضوع namespaceها در Xml داشتم دریافتم که وجود دو namespace فوق الذکر در ایکس‌ام‌ال‌های «ارسال» و «رسید» اجباری هستند. ضمنا هر نوع namespace دیگری که در ایکس‌ام‌ال‌های پروتکل قرار گیرند بی‌تاثیر و غیر ضروری بوده و بهتر است برای خوانایی بیشتر Xmlها حذف شوند.

‫خلاصه‌ای از مفاهیم Xml و Xml Namespace با نگاهی به پروتکل ECE

xml مدت‌ها بود که به دنبال فرصت مناسبی برای یادگیری بعضی اصطلاحات 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 علامت «کوچکتر از» یعنی "<" را وارد کنید بلکه به جای آن باید از ‪&lt;‬ استفاده شود. در بعضی حالات خاص اگر قرار باشد متنی که پر از علامت‌ها و کاراکترهای خاص هستند وارد شود دردسر زیادی به وجود خواهد آمد. ضمن آن که خوانایی متن هم کاهش می‌یابد. به عنوان نمونه به مثال زیر دقت کنید:
<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 
xmlns="http://www.irica.com/ECE/1383-12/SendSchema">

 

در مثال بالا تگ 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 زیر استفاده می‌شود:
//Letter/Subject

 

و این XPath اگر از ns مربوط به پروتکل ECE (Send) یعنی "http://www.irica.com/ECE/1383-12/SendSchema" استفاده شود به شکل زیر در می‌آید:

//ltr:Letter/ltr:Subject

 

در مثال دوم فرض شده است که 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 نوشته شده است.

 

مراجع:

‫پروتکل ECE و نرم افزارهای دبیرخانه

  ‫پروتکل ECE

پروتکل ECE یا پروتکل تبادل الکترونیکی مکاتبات (Electronic Correspondence Exchange) پروتکلی ایرانی است برای استاندارد کردن ارتباط مکانیزه نرم افزارهای دبیرخانه و اتوماسیون. ایده اولیه این پروتکل توسط کمیته نرم افزار انجمن شرکت‌های انفورماتیکی (زیر گروه همگن اتوماسیون اداری) در تابستان ۸۲ مطرح و در پاییز و زمستان ۸۳ عملیاتی گردید. در حال حاضر به دلیل انحلال انجمن شرکت‌های انفورماتیکی، سازمان نظام صنفی رایانه‌ای متولی امورات آن است.

تا قبل از ابداع این پروتکل خیلی از شرکت‌های نرم افزاری تولید کننده نرم افزار دبیرخانه و اتوماسیون برای برقراری ارتباط بین نسخه‌های مختلف نرم افزار خود که در مکان‌های جغرافیایی مختلفی نصب شده بودند روش‌های ارتباطی خاصی ابداع کرده بودند. این روش‌ها عمدتا مبتنی بر ارسال/دریافت نامه به کمک فایل‌های مختلفی مثل xml و روش‌های ارتباطی مثل ایمیل بودند. در ادارات و سازمان‌های بزرگ که هر کدام از شعب آن از یک نرم افزار دبیرخانه متفاوت استفاده می‌کردند برقراری ارتباط بین دبیرخانه‌های مختلف میسر نبود چون هر کدام از شرکت‌های تولید کننده نرم افزار از روش خاص خودش استفاده کرده بود. در اینجا بود که ایده پروتکل ECE مطرح شد. این پروتکل همه را ملزم می‌کرد تا از یک روش ارتباطی و قالب فایل یکسان استفاده کنند.

پروتکل ECE از یک فایل xml خاص با قالب کاملا مشخص به عنوان قالب ارسال/دریافت اطلاعات دبیرخانه‌ای و ایمیل به عنوان بستر ارتباطی استفاده می‌کند. کلیه مستندات پروتکل در سایت رسمی آن یعنی http://ecep.ir/ موجود است. در حال حاضر (بهار ۸۸) خیلی از شرکت‌های نرم افزاری در حال پشتیبانی از این پروتکل بوده یا درصدد افزودن آن به دبیرخانه‌هایشان هستند. ما هم امیدواریم این حرکت به ایجاد یک استاندارد واقعی و فراگیر تبدیل شود.

در ادامه لیستی از نوشته‌های خودم در وبلاگ قبلی‌ام که راجع به پروتکل ECE و نرم افزارهای دبیرخانه بود و بعضی لینک‌های دیگر را در جدول زیر می‌آورم. لطفا برای کامنت و لینک فقط از همین وبلاگ استفاده کنید چون وبلاگ قبلی دیگر به روز رسانی نمی‌شود.

کلیه مطالب وبلاگ جاری که راجع به پروتکل ECE هستند
نوشته ناصر حاجلو راجع به پروتکل ECE
سایت رسمی پروتکل ECE
سازمان نظام صنفی رایانه‌ای کشور – متولی رسمی پروتکل ECE
وبلاگ قبلی: معرفی وبلاگ
وبلاگ قبلی: جستجو در گوگل به دنبال ECE
وبلاگ قبلی: سیستم دبیرخانه بدون کاغذ، نیاز یا اجبار
وبلاگ قبلی: معیارهای انتخاب نرم افزار دبیرخانه (اتوماسیون)
وبلاگ قبلی: فرق بین دبیرخانه و اتوماسیون
وبلاگ قبلی: شرکت‌هایی که تفکیک دبیرخانه و اتوماسیون را به خوبی رعایت کرده‌اند
وبلاگ قبلی: یک سایت خوب برای آشنایی با سیستم‌های دبیرخانه
وبلاگ قبلی: مشکل در ارسال ایمیل
وبلاگ قبلی: Certify
وبلاگ قبلی: ویرایش جدید پروتکل تبادل الکترونیکی اطلاعات اداری ECE
وبلاگ قبلی: فعال شدن مجدد پروژه ECE

‫پروتکل ECE

‫مشکل Xml Name Space در پروتکل ECE‬

ابهامی در پروتکل ECE وجود دارد (یا شاید هم من آن را درست نفهمیده‌ام) که به واسطه آن نمی‌شود فهمید که آیا در XMLهای آن باید از xml name space استفاده شود یا نه؟ و اگر بله، از چه name spaceی؟ در هر صورت به خاطر این ابهام، نبودن ابزارهای تست و اعتبار سنجی و عدم پایبندی کامل خیلی از پیاده سازان پروتکل ECE بهتر است در پیاده سازی خودمان امکان خواندن هر دو نوع حالت را در نظر بگیریم و به صورت یک option در خارج از کدهای برنامه و در اختیار مسئول سیستم بگذاریم. آنچه که در پی می‌آید روش کار با Xml Name Spaceها با کمک XmlDocument و XPath در دات نت است.

همانطور که می‌دانید xml name space امکانیست در XML که با کمک آن می‌توان تگ‌های هم نام داشت بدون آنکه تداخل پیش بیاید. XPathی که برای یک تگ بدون name space نوشته می‌شود با آنی که برای یک تگ با name space نوشته می‌شود هم فرق دارد. مثلا XML زیر که بخشی از یک نمونه «ایکس‌ام‌ال ارسال» پروتکل ECE است را در نظر بگیرید:

<?xml version="1.0" encoding="utf-8"?>
<
Letter>
<
Protocol Name="ECE" Version="1.01" />
</Letter>

XPath استخراج اطلاعات نود Letter به شکل زیر است:

XmlNode xSend = xDoc.SelectSingleNode("//Letter");

حال اگر در فایل XML ما Xml NameSpace هم تعریف شده بود:

<?xml version="1.0" encoding="utf-8"?>
<
Letter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.irica.com/ECE/1383-12/SendSchema">
<
Protocol Name="ECE" Version="1.01" />
</Letter>

بایستی از XPath و کدهای کمکی زیر برای استخراج اطلاعات استفاده کرد:

XmlDocument xDoc = new XmlDocument();xdoc.Load(filename);
XmlNamespaceManager manager = new XmlNamespaceManager(xdoc.NameTable);manager.AddNamespace("xsi", "http://www.irica.com/ECE/1383-12/SendSchema");
XmlNode xSend = xdoc.SelectSingleNode("//xsi:Letter", manager);

‫دیدار عمومی سایت برنامه نویس، نمایشگاه الکامپ و پروتکل ECE

بعد از ظهر دوشنبه ۴ آذر ۸۷ را در نمایشگاه الکامپ ۸۷ بودیم. گردش علمی ما از گردهمایی اعضای انجمن برنامه نویس شروع شد. برای من که اولین بار بود که یک اجتماع Online را به صورت آدم‌های واقعی می‌دیدم موضوع جالبی بود. انگار که idهای انجمن زنده شده بودند و داشتند حرف می‌زدند! البته اگر یک برنامه از قبل تعریف شده مثل معرفی اعضا به هم، کارگاه، سخن‌رانی و یا… هم چاشنی آن می‌شد خیلی بهتر بود. امیدوارم جلسات بعد بهتر باشد.
در طول ۳ ساعت تقریبا همه غرفه‌های نرم افزاری را گشتیم. بیشتر نرم افزاری‌ها ارائه دهنده نرم افزارهای سازمانی مثل ERP، MIS و سیستم‌های حسابداری و انبار و… و پورتال بودند. مخاطب بیشتر آنها هم مشتریان دولتی و غیر دولتی بودند ولی ظاهرا بازدیدکنندگان عمدتا از کارمندان شرکت‌های کامپیوتری و برنامه نویسان بودند! در مورد مفید بودن نمایشگاه هم فکر می‌کنم نمایشگاه برای آنها که بدون هدف خاصی و صرفا برای با خبر شدن از اتفاقات جدید به نمایشگاه آمده بودند نمایشگاه خسته کننده‌ای بود ولی به لطف خدا برای ما که از همان اولش ارائه دهندگان پروتکل ارتباطی ECE و شرکت فارسی‌وب شریف را هدف گرفته بودیم چندان نمایشگاه عذاب آوری نبود. شرکت فارسی‌وب شریف را به آن علت که مستقیما درگیر استانداردهای ماتصا ۶۲۱۹ (ISIRI 6219) و ماتصا ۹۱۴۷ (ISIRI 9147) بودند علاقه داشتیم که ببینیم. این دو استاندارد آخرین استانداردهای موجود در زمینه پشتیبانی از زبان فارسی در محیط کامپیوتر و شبکه هستند.
با کمک ناصر حاجلو شرکت‌هایی را که حدس می‌زدیم دبیرخانه/اتوماسیون آنها از پروتکل تبادل الکترونیکی مکاتبات (ECE) پشتیبانی می‌کنند را مورد جستجو قرار دادیم. با این که بعضی‌ها حتی اسم این پروتکل را نشنیده بودند ولی نتیجه کار بد نشد، سه تا شرکت را پیدا کردیم که به گفته خودشان پروتکل ECE را به طور کامل پیاده سازی و تست کرده بودند و حاضر بودند پروتکل را بین نرم افزار خودشان و دبیرخانه ما تست کنند. البته جای بیشتر شرکت‌های موسس پروتکل و صد البته خود سازمان نظام صنفی که متولی رسمی پروتکل است حسابی خالی بود.
این هم عکس یادگاری اعضای انجمن (سایت) برنامه نویس:افسانه ۲۸ دلاور!‏
پ. ن.: عکس‌ها در پیکاسا هم موجود هستند.

‫مصائب پیاده سازی پروتکل ECE

تا زمانی که فقط صحبت از نوشتن کدهای پروتکل و تست آن با دبیرخانه خودتان است همه چیز مثل قند و عسل شیرین است. ولی وقتی که قرار شد این ارتباط با دبیرخانه‌های دیگر تست شود آن وقت می‌فهمید که زهر مار چه مزه‌ای است!

یکی از بزرگترین مشکلات و مصیبت‌ها عدم تست بیشتر دبیرخانه‌های موجود است چون بیشتر دبیرخانه‌های شرکت‌ها صرفا با خودشان تست شده و کار می‌کنند. برای این دسته از دبیرخانه‌ها هیچ وقت پیش نیامده که به دبیرخانه یا اتوماسیونی غیر از محصول شرکت خودشان نامه ECE بفرستند یا بگیرند. و در این حالت این بدبختی من برنامه نویس است که باید هم کدهای خودم را تست کنم و هم محصول شرکت‌های آن طرف خط را که بعضا مدت‌هاست روی کد مربوط به پروتکل کار نکرده‌اند و یا حتی برنامه نویس مربوطه از آن شرکت رفته است. این را هم بیفزایید که بعضی دوستان اصرار دارند از موضع برتر صحبت کرده و هیچ وقت قبول نمی‌کنند که برنامه‌ای که نوشته‌اند ایراد دارد یا این که پروتکل ارتباطی را بد فهمیده‌اند. مثلا یکی از شرکت‌ها که اتفاقا از شرکت‌های قدیمی ایران در امر نرم افزار است رشته زیر را به عنوان تاریخ نامه در XML ارسال می‌کند. در حالی که در پروتکل گفته شده که این رشته باید بر اساس استاندارد ISO 8601 باشد. در تعریف استاندارد ۸۶۰۱ هم گفته شده که این استاندارد بر مبنای تاریخ میلادی است و شامل هیچ رشته‌ای مثل +03:30 هم نمی‌باشد.

 1387-07-22T16:15:35+03:30

عدم رعایت کوچک و بزرگی حروف یا همان Case Sensitivity هم یکی دیگر از مشکلات رایج است. این مشکل در همه جا نمود دارد هم در هدرهای ایمیل و هم در XML تولیدی. مثلا فلان شرکت elementها و attirbuteهای XML را بدون توجه به این که XML به کوچک و بزرگی حروف حساس است تولید می‌کند و بهمان شرکت هم هدر ایمیل را با فرض حساس بودن به کوچک و بزرگ بودن حروف پردازش می‌کند در حالی که هدر ایمیل به حروف کوچک و بزرگ حساس نیست.

در مورد حساسیت هدر ایمیل به کوچکی و بزرگی حروف هم باید گفت که مطابق RFC 2822 و توضیحات اینجا حساس نیست. در اینجا هم گفته شده که نام هدر همیشه غیر حساس به حروف کوچک و بزرگ است ولی مقدار هدر بسته به حالت ممکن است حساس باشد یا نباشد. اگر از literal استفاده شود یعنی از حروف الفبای انگلیسی که محصور در دابل کوتیشن باشند مثل A و Header1 آن وقت حساسیتی وجود ندارد ولی اگر از از مقادیر داده‌ای که شبیه مقادیر اسکی دسیمال و… می‌باشد مثل «%d» قضیه فرق می‌کند.

‫راهی برای اضافه کردن دستی header به ایمیل‌ها

header بخشی از اطلاعات موجود در یک ایمیل است که با کمک آن می‌تواند قابلیت‌های زیادی به یک ایمیل بخشید. مثلا با اضافه کردن هدر خاصی به یک ایمیل می‌توان آن را به عنوان یک ایمیل ECE معتبر شناساند. خواندن هدر ایمیل‌های وارده تقریبا از همه برنامه‌های ارسال/دریافت ایمیل و کلاس‌های کار با ایمیل در دات نت امکان پذیر است. اما اضافه کردن هدر از طریق برنامه‌های ارسال/دریافت یا سرویس دهنده‌های ایمیل مثل جی میل و یاهو کار چندان ساده‌ای نیست. بعد از مدت‌ها گشت و گذار و تست کردن‌های مختلف فهمیدم که می‌توان با Customize کردن Thunderbird این کار را کرد. روش این کار در اینجا گفته شده است. من با کمک یک اکانت جی میل و Mozilla Thunderbird موفق شدم بدون هیچ مشکلی هدر مورد نظر خودم را به ایمیلم الصاق و آن را ارسال کنم. البته حتما می‌دانید که هدف از این کار تست دستی دبیرخانه‌هایی است که در دریافت ایمیل‌های دارای هدر ECE مشکل دارند.

اضافه کردن هدرهای دلخواه از طریق «مرغ طوفان»‏

این هم سورس تولیدی:

Message-ID: <48E8B367.9090709@gmail.com>
Date: Sun, 05 Oct 2008 16:00:31 +0330
From: ECE Tester <ece.tester@gmail.com>
User-Agent: Thunderbird 2.0.0.12 (Windows/20080213)
MIME-Version: 1.0
To: afshar.mohebbi@gmail.com
Subject: testing ece
X-ECE_SEND: 1.01


پ. ن.: Thunderbird برای ارسال فایل به همراه نامه مشکلاتی دارد که برای رفع
آن باید از این راه حل استفاده کرد.