بناء XPath؟ خوارزمية XPath؟ لا شيء سوى XPath

مرحبا عزيزي القراء. سوف يركز هذا المنشور على التطبيقات غير القياسية قليلاً مثل هذه الشكليات المعروفة مثل XPath. يعلم الجميع أنه مناسب جدًا لاستخراج المعلومات من XML أو HTML أو بعض مستندات ML * (نص عادي وبعض المستندات الافتراضية ، والتي تمثل الطبقة العليا لتمثيل أي معلومات معقدة) ، ثم هناك لطرح هذه الوثائق أي أسئلة. ومع ذلك ، فمن المعروف أنه كلما تمت صياغة السؤال بشكل أفضل ، كلما زاد عدد الإجابات التي يحتوي عليها بالفعل. لذلك ، يوحي التفكير البسيط نفسه: هل من الممكن استخدام التعبيرات المكتوبة في XPath كتأكيد ، أي بناء مستند بحيث يكون تعبير XPath هذا صحيحًا؟ أعتقد أن هذا ممكن ، وهذا هو أول ما سيتم مناقشته هنا. والثاني - إذا تعلمنا كيفية إنشاء عناصر جديدة مباشرة في مستند باستخدام XPath مباشرة ، فهل من الممكن تحويل XPath إلى لغة برمجة حسابية بسيطة؟ في الواقع ، إنه يعرف كيفية الوصول إلى البيانات ، ويعرف كيفية إنشاء البيانات. من السهل تخيل كيفية وصف تسلسل المشغلين والمشغل الفرعي فيه ، ويبقى التفكير في الدورات فيه والوظائف. هذا مثير للاهتمام ، على الأقل من الناحية النظرية. وسيتم أيضا مناقشة هذا.

بناء XPath


لذلك ، يصف XPath العادي سلسلة من الخطوات للتنقل خلال شجرة وثيقة ، ويمكن فرض شرط مرشح (مسند مكتوب بين قوسين مربعين) في كل خطوة. نتيجة لذلك ، نحصل على مجموعة محددة من العقد أو رقم أو سلسلة أو قيمة منطقية. نحن مهتمون في المقام الأول في حالة العقد المتعددة. ينتج XPath العادي عقدًا موجودة بالفعل في المستند. ضع في اعتبارك إنشاء XPath افتراضيًا لن يؤدي إلى إرجاع العقد الحالية فحسب ، ولكن أيضًا إنشاء عقد جديدة بطريقة تتوافق تمامًا مع الاستعلام.

الفكرة بسيطة للغاية - في الخطوة التالية من استعلام XPath ، سنقوم بتحليل عامل التصفية المتنبأ به ومتغيرات البيانات التي تندرج تحت هذا المرشح. وبعد ذلك سوف نتحقق من أي من هذه الخيارات موجودة بالفعل وسننتهي من بناء الخيارات غير الموجودة.

على سبيل المثال ، إليك استعلام:

/OBJS/Var[@A=1 and @B=1 or @A=2 or @A=3]/X 

إذا اعتبرناه بناءً ، فسنحقق أولاً مما إذا كان عنصر الجذر <OBJS> موجودًا ، وإن لم يكن ، سننشئه. التالي يأتي الخطوة فار مع مرشح. لن أصف القواعد التي تتم بها معالجة المرشح الأصلي حتى لا يعقد العرض التقديمي ، سأقول فقط إن هذا المرشح يصف بوضوح مجموعات البيانات الثلاث التي يكون صحيحًا فيها:

  1. <فار A = "1" B = "1" />
  2. <فار A = "2" />
  3. <فار A = "3" />

لذلك ، نحتاج إلى التأكد من أن عنصر <OBJS> يحتوي على عناصر <Var> تابعة لها هذه البيانات. وأخيرًا ، الخطوة التالية هي X بدون شرط - وهذا يعني أنه من الضروري أن يكون لكل عنصر Var عنصر فرعي <X>.

لذلك ، كل شيء بسيط. نتيجة لتطبيق مثل XPath للبناء ، على سبيل المثال ، على وثيقة

 <OBJS> <Var A=”2” /> </OBJS> 

نحصل على وثيقة الإخراج:

 <OBJS> <Var A=”2”> <X/> </Var> <Var A=”1” B=”1”> <X/> </Var> <Var A=”3”> <X/> </Var> </OBJS> 

وفي الوقت نفسه ، تمكنا بشكل حصري مع XPath ، دون XSL أو أي شيء من هذا القبيل.

خوارزمية XPath


لذلك علمنا XPath كيفية إنشاء البيانات. الآن علمه (قليلاً) معالجتها حسابيًا.

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

 A and B and C … and Z 

المشغل الشرطي للنموذج إذا كان (A) ثم B else C ، بالطبع (ولن أقول أي شيء جديد هنا) ، يمكن وصفه بتعبير منطقي
 A and B or C 

كل شيء أكثر تعقيدًا قليلاً مع الحلقة. لم أكن أرغب في تقديمه تمامًا مثل ذلك ، لذلك قررت فقط تقديم مفهوم وظيفة XPath ، والتي يمكن أن تكون متكررة. ومن ثم يمكن تمثيل أي دورة كسلسلة من المكالمات المتكررة مع التحقق من حالة الإنهاء.

من حيث المبدأ ، هذا هو كل شيء تقريبا (في الحد الأدنى من الإصدار). ليست هناك حاجة إلى المتغيرات - يتم استبدالها بعناصر من المستند الحالي. وسيطات الوظيفة المسماة فقط مطلوبة.

سأقدم مثالا. افترض أن لدينا مستندًا يحتوي على قائمتين من الأرقام الموصوفة في سلسلة من عناصر <list> المتداخلة:

  <a> <b> <list data="1"><list data="2"></list></list> </b> <c> <list data="3"><list data="4"></list></list></c> </a> 

دع الأمر ضروريًا لتسلسل القوائم من العنصر <b> وعنصر <c> ووضع النتيجة مباشرة في <a>. للقيام بذلك ، يجب تقديم ثلاث وظائف XPath:

 concat_list($#, $##): add_list(#/self::*) and add_list(##/self::*) add_list($#): count(list) = 0 and copy_list(#/self::*) or list[add_list(#/self::*)] or true() copy_list($#): count(#/list) = 0 or create(list[@data = #/list/@data]) and (list[copy_list(#/list)] or true()) 

وأضف XPath المتصلين إليهم:

 concat_list(/a/b,/a/c) 

آمل أن يكون لك أيها القراء الأعزاء اهتمامًا كبيرًا لفهم مثل هذا الرمز. الشيء الوحيد الذي سأذكره بالتأكيد هو إنشاء (XPATH) هي وظيفة نظام تنفذ وسيطة XPATH في وضع البناء.

والآن بعد أن أصبح كل هذا مثيرًا للاهتمام ، بالطبع ، إلا أن البرمجة بدون متغيرات لا تزال صعبة للغاية. أدركت ذلك ، قمت بتقديم متغيرات كاملة ، والتي ، في الواقع ، في XPath موجودة بالفعل - فهي تبدأ بعلامة "$" ، لكنني أضفت القدرة على تخصيص القيم لهم مع وظيفة المجموعة الجديدة. من فضلك ، فيما يلي مثال على وظيفة deep_list بوسيطتين - إشارة إلى العنصر الأولي الذي يحتوي على قائمة متداخلة من العناصر (كما في المثال أعلاه) ، ومتغير الإخراج الذي يحتوي على طول القائمة:

 depth_list($#, &$OUT1): set($OUT1,0) and (#/list[set($OUT1,1) and depth_list(#/list,$OUT0) and set($OUT1,max($OUT0+1,$OUT1))]) or true() 

استنتاج


في اللغة الصغرى الناتجة ، والتي أسميتها XPath Defender ، أضفت بعض الوظائف الضرورية واستخدمتها في نظامي للتعرف على برامج PGEN ++ وتوليدها للقيام بمهمة مهمة مثل الإكمال التلقائي لنموذج البرنامج المقدم كمستند XML. بمعنى آخر ، إذا كان هناك وصف نصي لمشكلة (من أجل الدقة ، باللغة الروسية) ، من الضروري إيجاد حل لها ، عندئذ يتم التعرف على هذا الوصف ويتحول إلى مجموعة مرتبة من عناصر بيان المهمة (كائنات ذات معلمات). هذا هو البيان الأولي ، الذي لا يحتوي حتى الآن على خطة لحل المشكلة. يتم وضع العناصر التي تم التعرف عليها في مستند XML ويتم تطبيق القواعد عليها ، ويتم كتابتها في شكل عبارات XPath بسيطة أو مُنشأة ، وفي شكل أجزاء على XPath Defender (هذا أحد خيارات سير العمل). تقوم هذه القواعد بالتحقق من نموذج مستند XML وتكميله بعناصر خطة الحل. وعندها فقط ، وفقًا للنموذج الذي تم الحصول عليه ، يقوم النظام ببناء برنامج حاسم. لقد تم اختبار هذه الدائرة بنجاح على المشاكل البسيطة للمعالجة الرياضية لبيانات المتجهات.

لكن مع ذلك ، فإن أهم نتيجة ، على ما أعتقد ، هي حقيقة أنه كان من الممكن إثبات أنه من الممكن بناء لغة برمجة حسابية ، باستخدام وسائل XPath بشكل حصري تقريبًا ، كان من الضروري إدخال وظائف فقط.

Source: https://habr.com/ru/post/ar464897/


All Articles