استكشاف أخطاء تنسيق المستند وإصلاحها هناك العشرات، إن لم يكن المئات، من الوصفات في قائمة والدتي. في حالة حدوث خطأ فادح، سيكون تصحيح الأخطاء أمرًا صعبًا للغاية - ستبحث عن العلامة المفقودة سطرًا تلو الآخر. إذا كنت تستخدم عدة مستويات من التداخل، فسيكون من الصعب العثور على الأخطاء.
ولكن يمكن العثور على مساعدة جيدة. الموزعون - التطبيقات التي تقوم بتحليل كود XML والإبلاغ عن الأخطاء المشوهة متاحة مجانًا عبر الإنترنت. أفضلها هو Lark، الذي كتبه تيم براي - المحرر الفني والمدافع الصوتي عن مواصفات XML، وهو أحد أذكى الأشخاص على هذا الكوكب.
أنا أستخدم Lark لتحليل الكود أدناه. لاحظ أن "رقائق الشوكولاتة" وعلامة الإغلاق الخاصة بها تظهران في موضع خاطئ داخل علامة </ingredients>:
<?xml version="1.0"?>
<list>
<recipe>
<author>Carol Schmidt</author>
<recipe_name >ألواح رقائق الشوكولاتة</recipe_name>
<meal>العشاء
<course>الحلوى</course
> </meal>
<ingredients>
<item>2/3 ج زبدة<
/item> <item>2 ج سكر بني</ item>
<item>1 ملعقة صغيرة فانيليا</item>
<item>1 3/4 ج دقيق غير منخول</item>
<item>1 1/2 ملعقة صغيرة بيكنج بودر</item>
<item>1/2 ملعقة صغيرة ملح< /item>
<item>3 بيضات</item>
<item>1/2 كوب مكسرات مقطعة</item>
<item>
</ingredients>2 كوب (12 أونصة لكل كجم) رقائق شوكولاتة نصف حلوة
< /item >
<الاتجاهات>
سخني الزبدة على حرارة 350 درجة، ثم
امزجيها مع السكر البني والفانيليا في وعاء خلط كبير، ثم
ضعيها جانباً حتى تبرد، ثم
أضيفي البيض إلى خليط السكر المبرد واتركيه
جانباًأضيفي
المكونات الجافة والمكسرات ورقائق البطاطس
إلى
صينيةمدهونة
مقاس 13 × 9 بوصة واخبزيها لمدة 25 إلى 30 دقيقة
حتى
تبرد.
list>
فيما يلي النتائج التي أرجعها المحلل:
سطرتقرير الخطأ
17، العمود 22: تمت مواجهة </ingredients> المتوقعة </item>
... المفترض </item>
السطر 18، العمود 36: تمت مواجهة </item> بـ لا يوجد علامة بدء
مع هذه المعلومات، لن يكون العثور على الخطأ مشكلة. إذن ماذا تعني صلاحية ملف XML؟
تنفيذ الفعالية في النهاية، سنضيف المعلومات إلى مستند XML جيد التنظيم. في الواقع، لدينا الكثير لنفعله - لا تزال هناك أزمات كامنة - وعلى الرغم من أن ملف XML منظم جيدًا،
ولكن من الممكن أيضًا فقدان المعلومات المهمة. ألقِ نظرة على المثال التالي:
<recipe>
<author>كارول شميدت</author>
<recipe_name>ألواح رقائق الشوكولاتة</recipe_name>
<وجبة>العشاء <كورس>الحلوى</كورس> </وجبة>
<المكونات> </المكونات>
<directions>تذوب الزبدة مع بعضها البعض... </directions>
</وصفة>
هذه الوصفة لا تتضمن المكونات، ولأنها منظمة بشكل جيد،
لن يجد محلل Lark المشكلة أيضًا. إن أي شخص أدار حتى أكثر قواعد البيانات حميدة يعرف الخطأ الذي نرتكبه نحن البشر: إذا أتيحت لنا الفرصة، فإننا نتخلص من المعلومات المهمة ونضيف هراء عديم الفائدة. ولهذا السبب قدم مخترع لغة XML DTD -
تعريف نوع الوثيقة. توفر DTDs طريقة للتأكد من أن XML هو ما تريده تقريبًا.
دعونا نلقي نظرة على DTD المستخدم في الوصفات.
<!قائمة DOCTYPE [
<!عنصر الوصفة (اسم الوصفة، المؤلف، الوجبة، المكونات، الاتجاهات)>
<!مكونات العنصر (العنصر+)>
<!عنصر وجبة (#PCDATA، بالطبع؟)>
<!عنصر العنصر (#PCDATA, sub_item*)>
<!عنصر وصفة_اسم (#PCDATA)>
<!مؤلف العنصر (#PCDATA)>
<!دورة العنصر (#PCDATA)>
<!عنصر العنصر (#PCDATA)>
<!عنصر فرعي (#PCDATA)>
<!اتجاهات العنصر (#PCDATA)>
]>
قد تبدو التعليمات البرمجية غير ودية في البداية، ولكنها تصبح منطقية عندما تقوم بتفكيكها. لنشرح ذلك بالتفصيل:
<!DOCTYPE list [
يشير هذا السطر إلى أن ما بين قوسين مربعين هو مستند يحتوي على العنصر الجذر <list>
دتد. وكما ذكرنا من قبل، فإن العنصر الجذري يحتوي على جميع العناصر الأخرى.
<!ELEMENT Recipe (recipe_name,meal,مكونات,الاتجاهات)>
يحدد هذا السطر علامة <recipe>. تعني الأقواس أن العلامات الأربع يجب أن تظهر في علامة <recipe> بالترتيب.
<!عنصر وجبة (#PCDATA، بالطبع؟)>
هذا السطر يحتاج إلى شرح مفصل. لقد حددت البنية التالية:
<meal>هنا اسم الوجبة إلزامي
<course>قد يظهر اسم مقرر دراسي واحد، ولكنه ليس كذلك
إلزامي</بالطبع>
</وجبة>
أفعل هذا لأنه، من وجهة نظري، لا يجب أن يكون الغداء بالضرورة طبقًا محددًا، لكن العشاء قد يشير إلى المقبلات والأطباق الرئيسية والحلويات. من خلال تحديد
#PCDATA - يمثل بيانات الأحرف التي تم تحليلها (أي البيانات غير الثنائية) لتنفيذ هذه الوظيفة. هنا، #PCDATA عبارة عن نص - على سبيل المثال، "dinner".
تشير علامة الاستفهام بعد "الدورة التدريبية" إلى ظهور 0 أو زوج واحد من علامات <course> في <meal>
داخل العلامة.
الآن دعونا نلقي نظرة على السطر التالي:
<!ELEMENTمكونات (item+)>
تشير علامة الزائد هنا إلى أن زوجًا واحدًا على الأقل من علامات <item> يجب أن يظهر في <ingredients>
داخل العلامة.
السطر الأخير الذي يهمنا هو:
<!ELEMENT item (#PCDATA, sub_item*)>
لقد وضعت sub_item* كإجراء أمني. بالإضافة إلى السؤال عن نص كل عنصر، أرغب في حساب مقدار المحتوى لكل عنصر. تشير العلامة النجمية إلى عدد العناصر الفرعية التي يمكن تضمينها في العلامة <item>. لا أحتاج إلى أي عناصر فرعية لوصفة ألواح رقائق الشوكولاتة، لكن هذا مفيد عندما تكون المكونات معقدة.
الآن دعونا نجمع هذا معًا ونرى ما سنحصل عليه.
مثال كامل لـ DTD فيما يلي مثال كامل. أضفت وصفة أخرى إلى الملف وأضفتها
تم شرح DTD. يمكنك ملاحظة أنني استخدمت عناصر فرعية في الوصفة الثانية.
<?xml version="1.0"?>
<!--يبدأ هذا DTD الأسطر الأربعة الأولى تتناول بنية المستند-->
<!قائمة نوع DOCTYPE ][
<!عنصر الوصفة (اسم الوصفة، المؤلف، الوجبة، المكونات، الاتجاهات)>
<!مكونات العنصر (العنصر+)>
<!عنصر وجبة (#PCDATA، بالطبع؟)>
<!عنصر العنصر (#PCDATA, sub_item*)>
<!--هذه هي العناصر المتبقية من علامة الوصفة -->
<!عنصر وصفة_اسم (#PCDATA)>
<!مؤلف العنصر (#PCDATA)>
<!اتجاهات العنصر (#PCDATA)>
<!--العنصر المتبقي من علامة الوجبة -->
<!دورة العنصر (#PCDATA)>
<!--العنصر المتبقي من علامة العنصر -->
<!ELEMENT sub_item (#PCDATA)>
]>
<?xml version="1.0"?>
<قائمة>
<وصفة>
<author>كارول شميدت</author>
<recipe_name>ألواح رقائق الشوكولاتة</recipe_name>
<وجبة>العشاء
<كورس>حلوى</كورس>
</وجبة>
<المكونات>
<item>2/3 ج زبدة</item>
<البند>2 ج سكر بني</البند>
<item>1 ملعقة صغيرة فانيليا</item>
<item>1 3/4 ج دقيق متعدد الأغراض غير منخول</item>
<item>1 1/2 ملعقة صغيرة بيكنج بودر</item>
<item>1/2 ملعقة صغيرة ملح</item>
<البند>3 بيضات</البند>
<item>1/2 ج مكسرات مقطعة</item>
<item>2 كوب (12 أونصة لكل كجم) من رقائق الشوكولاتة نصف الحلوة</item>
</المكونات>
<الاتجاهات>
سخني الفرن إلى 350 درجة تذوب الزبدة.
يُمزج مع السكر البني والفانيليا في وعاء خلط كبير.
يُترك جانباً ليبرد ويُمزج بين الدقيق والبيكنج باودر والملح.
يُترك جانباً ويُضاف البيض إلى خليط السكر المبرد ويُخفق جيداً.
ضجة في المكونات الجافة المحفوظة والمكسرات ورقائق البطاطس.
يُوزّع في مقلاة مدهونة مقاس 13 × 9 بوصة.
اخبزيها لمدة 25 إلى 30 دقيقة حتى يصبح لونها بنياً ذهبياً.
قطع إلى مربعات.
</الاتجاهات>
</وصفة>
<وصفة>
<recipe_name>معكرونة بصلصة الطماطم</recipe_name>
<وجبة>العشاء
<كورس>مدخل</كورس>
</وجبة>
<المكونات>
<item>1 رطل معكرونة</item>
<item>1 علبة طماطم مقطعة بوزن 16 أونصة</item>
<item>4 فصوص ثوم</item>
<item>1 بصلة مقطعة</item>
<البند>التوابل الإيطالية
<sub_item>الزعتر البري</sub_item>
<sub_item>ريحان</sub_item>
<sub_item>فلفل أحمر مطحون</sub_item>
</البند>
</المكونات>
<الاتجاهات>
تُسلق المعكرونة ويُقلى الثوم والبصل.
أضيفي الطماطم وقدميها ساخنة.
</الاتجاهات>
</وصفة>
</قائمة>
الآن بعد أن أصبح هناك DTD، سيتم فحص المستند لمعرفة ما إذا كان يتوافق مع القيود التي وضعها DTD. بمعنى آخر، نريد التأكد من صحة الوثيقة.
ولتحقيق ذلك، نحتاج إلى أداة أخرى: محلل الصلاحية. يعد MSXML من Microsoft، وهو برنامج قائم على Java، سهل الاستخدام ويعمل بشكل جيد. تم فحص الوثيقة أعلاه بواسطة هذا البرنامج ولم يتم العثور على أية أخطاء. ولكن إذا قمت بالتحقق من أ
الوصفات التي لا تحتوي على عنصر في علامة المكونات ستعرض الرسالة التالية:
المكونات غير كاملة [العنصر].