الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

xml

مغلق
بدأه cold0zero في 1 يوليو 2003 · 0 رد · 895 مشاهدة · في منتدى تصميم صفحات الويب
مشاركة: واتساب X فيسبوك تيليجرام
#1

أحد المواضيع الذي يغفل المبرمجون كثيراً الحديث عنه خلال النقاشات المتعلقة

بلغة XML (Extensible Markup Language)، هو لغة تحويل XSL (XSL

Transformation Language ، XSLT).

ويقع اللوم في ذلك جزئياً على قلة الوعي بفوائد تلك اللغة، التي تسمح بإنشاء

صفحة نمط (Style sheet)، لمعالجة وثيقة XML. وتستطيع داخل وثيقة XSLT، أو

صفحة نمط أن تمسح وثيقة XML بحثاً عن العناصر والصفات، وغير ذلك، وتعالجها

كلما صادفتها. ويرى كثير من المبرمجين أنه يمكن إنجاز تلك المهمة باستخدام

وظائف واجهة برمجة التطبيقات (API)، مثل وظائف SAX (Simple API for XML)، أو

وظائف DOM (Document Object Model). والحقيقة أن للغة XSLT، ووظائف واجهة

برمجة التطبيقات (API) مثل DOM وSAX، مزايا مشتركة، تسمح لك بإنجاز مهمات

متماثلة. لكن لغة XSLT، تمتاز بحسنات ربما غفل عنها المبرمجون. وإحدى تلك

الحسنات التي تصيب قلب الهدف من لغة XML، هي فصل البيانات عن خوارزمية

البرنامج، وعن شيفرة الإظهار. ولأن لغة XSLT لا تربط بمنصة معينة، أو بشيفرة

خاصة بتطبيق معين، فإنها تسمح بتحويل بياناتك المنفصلة إلى أي تنسيق تختاره،

وجمعها مع شيفرة التطبيق، وإعادة توزيعها على أي جهاز متوفر، مثل أجهزة بالم،

وحواسيب سطح المكتب، والهواتف التي تدعم الوصول إلى إنترنت. والنقطة المهمة

هنا، أن لغة XSLT تسمح لك بعرض البيانات ذاتها بعدة أساليب في وقت واحد. بل

يمكنك استخدامها لإعادة توجيه البيانات إلى أجهزة لم توجد بعد، وإعادة تقديم

البيانات ذاتها بطرق لم يتخيلها رئيسك في العمل.

الهدف الرئيس من لغة XSLT، هو تحويل البيانات بسهولة إلى هيئات أخرى، مثل

HTML، أو تحويل XML من مفردات معينة إلى أخرى. وإذا كنت تحتاج إلى إجراء

العديد من التحويلات، يمكنك أن تعرّف تشكيلة من صفحات الأنماط، التي تحول

بياناتك بطرق مختلفة.

الشيء المؤسف أن صفحات الأنماط الساكنة يمكن أن تسبب مشكلات توالد مزعجة.

وذلك حين يقود حتى تطبيق بسيط أحياناً، إلى تطوير مئات من صفحات الأنماط.

وكخطوة أولى في سبيل حل تلك المشكلة، سوف نشرح كيف تستخدم وظائف DOM كي تولد

صفحات أنماط XSLT ديناميكية من نص برمجي. وتستطيع باستخدام منطق برمجي إضافي،

استبدال ما قد يصل إلى مئات من صفحات الأنماط، بنص برمجي واحد.

لماذا نولد XSLT ديناميكياً؟

تبرز مشكلات التعامل مع صفحات الأنماط الساكنة عندما يكون لديك متغيرات

عديدة، ما قد يؤدي إلى الحاجة إلى توليد مئات من صفحات الأنماط. ونوضح ذلك

عبر المثال التالي: لنفترض أن لديك موقع ويب يستخدم XSLT لتنسيق شيفرة HTML

في الصفحات بحيث تناسب متصفحات مختلفة. ستحتاج عندها إلى صفحة نمط ساكنة، كي

تولد شيفرة HTML، لكل نوع من المتصفحات وكل إصدارة منها،. ويعني هذا أنه

سيكون لديك صفحة نمط تولد شيفرة HTML خاصة لإنترنت إكسبلورر 5، وأخرى تخرج

شيفرة HTML لنتسكيب نافيجيتور 4، وهكذا. وستحتاج لذلك إلى دستة من صفحات

الأنماط لدعم المتصفحين الرئيسين فقط (بدءاً من إنترنت إكسبلورر 1 وحتى 5.5،

ومن نتسكيب نافيجيتور 1 وحتى 5). وافترضنا في المثال السابق أننا نتحدث عن

نوع واحد من وثائق XML، لكن مواقع ويب تقدم عادة، أنواع مختلفة من الوثائق

(صفحة جدول محتويات، صفحة قاعدة بيانات، صفحة مقال، صفحة نموذج إدخال،

وهكذا)، فإذا افترضنا أن عدد أنواع الوثائق محدود بعشرة، فإننا سنحتاج إلى

120 (10×12) صفحة نمط لدعم إظهار جميع أنواع الوثائق في المتصفحين الرئيسين

لإنترنت. ولو توقف توالد صفحات الأنماط المطلوبة عند هذا الحد، لهان الأمر،

لكن حتى استخدام 120 صفحة نمط يصبح غير كافياً، إذا افترضت أن الموقع يسمح

للزوار باختيار واحدة من أربع واجهات استخدام مختلفة السمات. وتحتاج كل واجهة

إلى صفحة نمط لتجسيد محتويات الوثائق ذاتها، لكن بمظهر مختلف داخل المتصفح.

ويعني هذا أنك ستحتاج كي تدعم الإظهار في المتصفحين الرئيسين، لدى استخدام

عشرة أنواع وثائق، وأربع سمات، إلى 400 صفحة نمط. ويمكن لهذا العدد أن يسبب

لك صداعاً مؤلماً، حتى إذا أردت أن تجري مجرد تغيير بسيط على بنى أنواع

الوثائق، التي تؤثر بدورها على صفحات الأنماط. أن الجزء الأكبر من كل صفحة

نمط، من تلك الصفحات، سيكون مماثلاً تقريباً لصفحات الأنماط الأخرى. وسيتطلب

تجسيد السمات مجرد استيراد صفحة نمط متعاقب (Cascading Style Sheet) مختلفة.

ويعني هذا أن السطر الوحيد الذي يتغير في وثيقة XSLT، هو ذلك المرتبط بملف

CSS. ويمكن استخدام برنامج أو نص برمجي لتوحد التقنيات المقدمة هنا، عبر

تعليمات Case أو Switch، للتعامل مع أنواع وثائق مختلفة، وأنواع متصفحات

مختلفة، وسمات مختلفة. ويجب أن تضيف كل تعليمة Switch تعديلات صغيرة تحتاجها

صفحة النمط. لكن هذا تطبيق متعلق بجهة المزود، ويقع خارج نطاق هذه المقالة.

تحويل XML

قبل أن تبدأ في كتابة (أو توليد)، تحويلاتك، من المهم أن تفهم كيف تتم معالجة

صفحات الأنماط. يقرأ محلل (parser) لغة XML، الوثيقة المعلّمة، وينشئ بنية

شبيهة بالشجرة في الذاكرة. وتحتوي تلك الشجرة على العناصر، والصفات،

والكائنات، والحواشي، وتعليمات معالجة الوثيقة. ويمكنك بعد هذه المرحلة، أن

تسير ضمن الشجرة، وتصل وتعدل تلك المكونات المعلّمة، في ترتيب الوثيقة،

باستخدام وظائف واجهة برمجة التطبيقات للغةXML ، مثل وظائف DOM، أو SAX.

ويمكنك أيضاً أن تطلب من معالج XSLT، أن يأخذ تلك الكائنات، ويحولها، ويخرجها

(نظرياً) بأي طريقة تتخيلها. ويأخذ معالج XSLT، الشجرة التي ولدها معالج XML،

(وهي الشجرة المصدر)، وينشئ شجرة جديدة (وهي الشجرة الهدف)، تتضمن جميع

العناصر المحولة.

وكي ترى كيف تتم تلك العملية، انظر إلى الشكلين 1 و2. فالملف Rocket.XML

(الشكل 1) وثيقة XML بسيطة، والملف Stylesheet.xsl (المعروض جزئياً في الشكل

2) يتضمن صفحة نمط من نوع XSLT، تستطيع تحويل وثيقة XML تلك إلى شيفرة HTML.

وكما ترى من خلال الإعلان عن xml، فإن صفحة النمط من نوع XSLT هي أيضاً وثيقة

XML منسقة جيداً، يمكن أن تستخدم لإنشاء صفحات أنماط جديدة ديناميكياً (أي في

وقت التشغيل). وتتألف البنية الأساسية لصفحة النمط من قالب الجذر (root

template) (كما يلاحظ من) وسلسلة من عناصر . ونريد داخل قالب الجذر، أن نعالج

عقدة الجذر، والعقد التي تمثل الأبناء المتفرعين عنها مباشرة. ولهذا نستخدم

للحصول على العناصر headline، وdeck، وbyline، وaBody، وإدراجها ضمن التحويل

إلى شيفرة HTML. وتستخدم القوالب الإضافية لمعالجة السلالة المتحدرة من

العنصر aBody.

وبالمناسبة، فأنا أستخدم حيلة صغيرة في صفحة النمط لتجسيد عناصر XML. حيث

ضمّنت في التحويل واصفة من لغة HTML، والتي تقرن صفحة الأنماط المتعاقبة CSS،

مع خرج HTML الخاص بنا. وغلفت العناوين الرئيسة، والأرضية، والخط الجانبي،

وما شابهها، بواصفات

لإظهار هذه العناصر المحولة. وتقابل صفة CLASS للواصفة

، النمط الذي أنشأته في صفحة الأنماط المتعاقبة CSS. ولهذا عندما تتم معالجة

وثيقة XML، فإن صفحة الأنماط تحول عناصر XML إلى HTML، وتستخدم قواعد النمط

الموجودة في صفحة الأنماط المتعاقبة CSS لتعيين شكل التنسيق في شيفرة HTML

الناتجة. وإذا تم عمل هذا التحويل على المزود، فإن المتصفح يرى فقط شيفرة

HTML، ولا يدرك حدوث خدمة تقديم وثيقة XML. ويمكنك أن تستخدم هذا الأسلوب

لإظهار أي وثيقة XML باستخدام صفحات الأنماط المتعاقبة CSS. وهذا باختصار

الأسلوب الذي تستطيع من خلاله استخدام صفحات الأنماط المتعاقبة CSS، لإظهار

أي وثيقة من نوع XML.

صفحات الأنماط الديناميكية

لأن صفحات الأنماط وثائق صحيحة منسقة جيداً، يمكنك أن تحمل أي صفحة نمط داخل

وظائف DOM، كما تفعل مع أي وثيقة من نوع XML. وسنستخدم هذه الميزة كي نحمل

صفحة نمط بسيطة داخل كائن DOM، ثم نستخدم طرق (methods) كائن DOM لبدء إنشاء

مثل من صفحة النمط. وهدفنا أن ننشئ برنامجاً يولد تلقائياً صفحة النمط

المبينة في الشكل 2. ويمكنك حالما يتم إنشاء صفحة النمط، أن تحفظها على القرص

أو تطبقها مباشرة على أي وثيقة من نوع XML.

وكي تختبر مثالي بسهولة، كتبته كبرنامج بلغة جافاسكريبت داخل شيفرة HTML. لكن

يمكنك إجراء بعض التغييرات الصغيرة عليه، ليعمل ضمن صفحة مزود فعّالة (Active

Server Page). ويمكنك أيضاً تطبيق التقنيات ذاتها (مع بعض الاستثناءات

الصغيرة)، مع أي محلل للغة XML، أو لغة برمجة، إذا استخدمت وظائف DOM.

عليك لبدء التعامل مع وظائف DOM، أن تنشئ كائن DOM جديداً، وتحمّل وثيقة XML

داخل ذلك الكائن. وتستطيع بعد هذه المرحلة استخدام طرق DOM، للتحرك ضمن شجرة

الوثيقة، والوصول إلى العقد، والاستعلام عن الخصائص، وتعديل العقد، وإنشاء

عقد جديدة، وهكذا. لكن الأمر المؤسف أن أدوات إنشاء وتحميل كائنات DOM، تتعلق

بالمحلل الذي تستخدمه. وأستخدم في هذا المثال، المحلل MSXML من مايكرسوفت،

ويعني ذلك أن هذا الجزء من الشيفرة خاص بمحلل مايكروسوفت، بينما يفترض أن

يعمل الجزء الباقي من الشيفرة المقدمة مع أي محلل خاضع لمواصفات DOM من

المستوى الأول (DOM Level 1). يضاف إلى ذلك، أن شيفرة إنشاء كائن DOM،

باستخدام محلل مايكروسوفت، تختلف حسب الجهة التي تعمل عليها، والتي يمكن أن

تكون جانب الزبون أو جانب المزود. فلإنشاء كائن DOM جديد، في تطبيق زبون،

يمكنك أن تستخدم طريقة ActiveObject() جديدة، وتعين النتيجة إلى متغير. وتجد

هذا الأسلوب مستخدماً في المثال ضمن الملف Genxsl.hta. أما إذا أردت أن تنشئ

كائن DOM، على جانب المزود، عبر صفحة Active Server Page، مثلاً، فيجب أن

تستخدم الطريقة Server.CreatObject() بدلاً من ذلك.

الملف Genxsl هو وثيقة HTML، تتضمن وظيفة بلغة جافاسكريبت تدعى Parse().

ولاحظ أن واصفة ، لوثيقة HTML تتضمن ONLOAD="Parse()"، التي تستدعي وظيفة

Parse() حالما يتم تحميل شيفرة HTML في المتصفح. الخطوة الأولى في الوظيفة

Parse()، إنشاء كائن DOM جديد كما بينّا سابقاً. لكن ستلاحظ أنني ضمنت ثلاثة

نداءات مختلفة لإنشاء كائن DOM، وجعلت اثنان منهما على شكل تعليق:

// Create a Document object and report the results.

// The following instantiate different versions of the MSXML parser

// Version 1 ProgID: Microsoft.XMLDOM

// Version 2 ProgID: MSXML2.DOMDocument

// Version 3 ProgID: MSXML2.DOMDocument.3.0

// var xslDocument = new

ActiveXObject("Microsoft.XMLDOM");

// var xslDocument = new

ActiveXObject("MSXML2.DOMDocument");

var xslDocument = new

ActiveXObject("MSXML2.DOMDocument.3.0");

وكما ترى من هذه التعليقات، أن كل من تلك النداءات خاصة بإصدارة مختلفة، من

المحلل MSXML. والملف Genxsl الذي قدمته في هذه المقالة، يعمل مع الإصدارة 3

من محلل MSXML، (انظر الصفحة http://msdn.microsoft.com/xml، للحصول على آخر

إصدارة من محلل MSXML)، وإذا كنت تريد تشغيل الإصدارة 1 من محلل MSXML، ضع

إشارات التعليق على السطور التي تعود إلى الإصدارة 3 من المحلل، وأزل

التعليقات عن الشيفرة الخاصة بالإصدارة 1 منه.

وفي جميع الحالات، ستعطى نتيجة هذه العملية للمتغير xslDocument. لهذا فإن

الخطوة التالية هو ملء xslDocument بهيكل ملف من نوع XSLT، هو Template.xsl،

المبين في الشكل 3. ويتم هذا باستخدام الطريقة load(). وكما في حالة إنشاء

كائن DOM، فإن طريقة ملء كائن DOM، خاصة بالمحلل الذي تستخدمه، أي أن هذا

السطر يجب أن يتغير وفقاً للمحلل الذي تستخدمه.

بناء قواعد القالب

تستطيع بعد ملء الكائن xslDocument، أن نستخدم طرق DOM، لبناء صفحة النمط

الخاصة بنا، (كتلك المبينة في الشكل 2). ولأن وثيقة XSLT الهيكل، تحتوي على

عنصر فارغ فقط، فإن المهمة الأولى، هي إنشاء قالب الجذر. يستخدم Genxsl طريقة

createElement() من طرق DOM، لإنشاء عنصر جيد يدعى xsl:template. لكن إنشاء

هذا العنصر الجديد، لا يدرجه تلقائياً ضمن شجرة الوثيقة. ولهذا استدعيت

الطريقة appendChild() لإدراج العنصر xsl:template كآخر ابن للعقدة . وبعد أن

أصبح العنصر الأخير ضمن الشجرة، استخدمت الطريقة setAttribute()، لإدراج

الصفة-القيمة match="/"، ضمن العنصر ، والمعرّف كعقدة الجذر.

ونريد عند هذه النقطة، أن نبدأ بإضافة شيفرة HTML، الذي سيستخدم في تحويلنا.

حاولت بداية، أن أدرج واصفات HTML على شكل نص. لكن عندما تمت معالجة الوثيقة،

تم استبدال رموز العلامات، بكينونات (Entities) معرفة مسبقاً. فتمت إعادة

كتابة الواصفة ، مثلاً، بالشكل &1t;HTML>. وأدركت بعد ذلك أنني أستطيع ببساطة

إدراج واصفات HTML، وكأنها علامات للغة XML. إذ لا يهتم المعالج بنوع

العلامة، فهو يعتقد أن كل شيء هو شيفرة XML. ولهذا يستخدم الملف Genxsl

ببساطة الطريقة createElement()، مرة أخرى، لإنشاء واصفات HTML، وBODY،

وLINK.

لكن التحدي الأكبر هو إدراج عناصر HTML تلك، داخل شجرة الوثيقة. ومثال ذلك أن

عنصر فرعي من ، والأخير عنصر فرعي (أو محتوى) من . وعند إدراج العنصر ، ينتقل

Genxsl من العقدة الجذر (documentElement) إلى الطفل الأخير (lastchild)،

ويضيف العنصر الذي تم إنشاءه أخيراً، إلى قائمة هذه العقدة، من العقد

الفرعية. ويعني هذا أن إضافة ، كعنصر فرعي من ، أمر أسهل قليلاً، وذلك حين

ينادي Genxsl ببساطة، الطريقة appendChild().

يتم في الخطوة التالية، توليد الواصفة LINK، وإدراج واصفات DIV في الوثيقة.

وكما ذكرنا سابقاً، تجلب واصفة LINK صفحة أنماط متعاقبة، وتستفيد واصفات

، من تلك الأنماط لتنسيق شيفرة HTML المولدة.

الخطوة الأخيرة، في هذا المثال البسيط، هي إدراج محتويات XML الخاصة بنا،

داخل واصفة

. ويتم هذا عبر لغة XSLT، باستخدام . يستدعي Genxsl مرة أخرى الطريقة

createElement()، لإنشاء لكل قطعة من البيانات نريد أن نعود بها، ويضبط صفة

الاختيار كي تطابق بيانات XML التي نريد أن نقدمها، ويدرج العنصر في شجرة

الوثيقة، عند النقطة التي يرد فيها عنصر

. وفي المرحلة الأخيرة، يسجل النص البرمجي في الملف Gensxl، شجرة الوثيقة

الناتجة على القرص، ما يسمح لك بعرض النتائج سريعاً. ولتختبر هذا المثال،

اربط صفحة النمط إلى وثيقة XML الخاصة بك، مستخدماً تعليمة المعالجة ، ثم شغل

وثيقة XML في متصفح إنترنت إكسبلورر لمشاهدة التحويل الناتج.

تشغيل المثال

لتشغيل هذا المثال، انسخ جميع الملفات من القرص المدمج الملحق بالمجلة (من

الدليل XMLtoHTML))، إلى الدليل الذي تعمل فيه. ولا تقلق بشأن الملف

Stylesheet.xsl، لأن الملف Genxsl.hta سوف يولده آلياً. ولاحظ أننا يجب أن

نستخدم الامتداد hta، بدلاً من html، لأن هذا النص البرمجي يسجل الملف

Stylesheet.xsl على القرص، ما يؤدي بسبب قيود الأمن في المتصفح، إلى تلقي

رسالة خطأ، إذا حاولت أن تعطي ملفك الامتداد html.

بعد تنفيذ ما سبق، ستصبح قادراً على تشغيل النص البرمجي Genxsl.hta، وسيظهر

خلال لحظات الملف Stylesheet.xsl، ويمكنك عندها إطلاق Rocket.xml. وتحتوي

الوثيقة على إعلان صفحة الأنماط التي تربط Stylesheet.xsl، وبهذا سيظهر الملف

Rocket.xml في متصفحك كما يبدو في الشكل 4.

الخلاصة

يمكنك التخلص من كابوس صيانة صفحات الأنماط الساكنة، باستخدام الأسلوب المقدم

في هذه المقالة، الذي يستبدل عدداً كبيراً من صفحات الأنماط الساكنة التي يجب

أن تكتبها، بنص برمجي وحيد. التطبيق الآخر لتوليد صفحات الأنماط الديناميكية،

هو تحويل صفحات الأنماط القديمة كي تتوافق مع المواصفات القياسية الأحدث للغة

XSL، وحتى إذا لم تكن تطور صفحات أنماط، فإن التقنيات المقدمة في هذه

المقالة، سوف تكون مفيدة لكل من ينشئ وثائق XML معقدة مستخدماً وظائف DOM.

هذا الموضوع مغلق.

مواضيع مشابهة