§

اختبار تعبيرات JSONPath

صيغة الناتج:
مرجع سريع لـ JSONPath
Token Meaning
$العنصر الجذر للمستند
@العنصر الحالي (يُستخدم داخل تعبيرات التصفية)
.عامل العضو الفرعي: يختار عضواً مُسمَّى
..النزول التكراري: يبحث في كل السلالات
*البدل: يُطابق أي عنصر أو خاصية
[*]جميع عناصر المصفوفة
[n]عنصر المصفوفة عند الفهرس n (يبدأ من الصفر)
[start:end]شريحة المصفوفة من start حتى (دون تضمين) end
[?(@.x)]تصفية: العناصر التي توجد فيها الخاصية x
[?(@.x==1)]تصفية: العناصر التي تساوي فيها الخاصية x القيمة 1
[(@.length-1)]تعبير سكريبت: آخر عنصر في المصفوفة

يظهر JSONPath في كل مكان يجب فيه التحقق من عقد واجهة برمجة تطبيقات مقابل حمولة حقيقية. فرق fintech الأمريكية التي تكتب مجموعات انحدار Postman تُقرّر حقول الاستجابة بـ JSONPath في تبويب Test، وسكريبتات اختبار الحمل k6 تسحب القيم من أجسام استجابات API بـ jsonpath() لتضع حدود SLA داخل كتل check()، وكتب تشغيل SRE في الاستجابة للحوادث تلجأ إلى تعبيرات التصفية كـ [?(@.status=="error")] لتقطيع سجلات CloudWatch JSON قبل التنبيه. تشغيل تلك التعبيرات في تبويب متصفح يُبقي حمولات التركيبة الخاصة وبيانات PII للعملاء واستجابات API قبل الإصدار خارج أي خدمة استعلام مستضافة.

ما هو JSONPath؟

JSONPath هو لغة استعلام لمستندات JSON، مكافئ JSON لـ XPath لـ XML. اقترحه Stefan Goessner عام 2007 طريقةً قصيرة وقابلة للقراءة للإشارة إلى عقدة داخل شجرة JSON دون كتابة محلل. يبدأ التعبير بمحدد الجذر $ ويسلسل موصّلات الخصائص ومقادير المصفوفات والبدلات والنزول التكراري وشروط التصفية حتى يختار العقد المطلوبة. نشرت IETF عام 2024 RFC 9535 لتوحيد الصياغة التي تشعّبت عبر التطبيقات؛ يعمل هذا المُختبر على jsonpath-plus وهو تطبيق JavaScript مُستخدَم على نطاق واسع يغطي مسودة Goessner ومعظم RFC 9535 وعدة عوامل إضافية.

كيف يعمل JSONPath؟

يُقرأ تعبير JSONPath من اليسار إلى اليمين ويمشي على مستند JSON خطوةً بخطوة. كل خطوة تأخذ مجموعة العقد التي نجت من الخطوة السابقة وتُضيِّقها أكثر. خط أنابيب التقييم الكامل:

  1. الإرساء بمحدد الجذر $. كل تعبير يبدأ هنا، مشيراً إلى القيمة على أعلى مستوى سواء كانت كائناً أو مصفوفة. أسماء الخصائص المجردة بدون $ بادئ ليست JSONPath صالحة.
  2. الدخول في الأعضاء الفرعية بالتدوين النقطي ($.store.book) أو تدوين الأقواس ($['store']['book']). تدوين الأقواس مطلوب حين يحتوي المفتاح على مسافة أو واصلة أو أي محرف ليس معرّفاً صالحاً.
  3. البحث في كل مستوى دفعةً واحدة بعامل النزول التكراري ... التعبير $..author يجمع كل قيمة author في أي مكان في الشجرة بغض النظر عن العمق. هذا هو العامل الذي لا تملكه JMESPath.
  4. اختيار عناصر المصفوفة بالفهرس ([0]، [-1] للعنصر الأخير في jsonpath-plus)، أو شريحتها بتدوين [start:end] ([0:3] يُرجع الثلاثة الأولى)، أو الإمساك بكل عنصر بالبدل [*].
  5. تصفية العناصر بمحمول داخل [?(...)]. داخل المحمول، @ يُشير إلى العنصر الحالي، فـ [?(@.price<10)] يُبقي فقط العناصر التي يقل فيها حقل price عن 10. تتكوّن التصفيات مع بقية المسار، فيمكنك التصفية ثم النزول، أو النزول ثم التصفية.
  6. اختيار صيغة الناتج. القيم يُرجع البيانات المُطابَقة نفسها. المسارات يُرجع JSONPath لكل تطابق كي ترى ما حلّه المحرك. المؤشرات يُرجع مؤشر RFC 6901 JSON المكافئ لكل تطابق، مفيد حين المُستهلَك النهائي هو JSON Patch أو مدقق مخطط JSON.

لماذا تستخدم هذا المُختبر؟

  • JSON الخاص بك لا يغادر المتصفح. الاستعلام يُشغَّل داخل الصفحة، لذا تبقى التركيبات الإنتاجية وبيانات PII للعملاء واستجابات API قبل الإصدار على جهازك.
  • المحرك هو jsonpath-plus 9.x، المكتبة ذاتها التي تدعم كثيراً من مجموعات الاختبار الإنتاجية وتأكيدات CI. النتائج التي تراها هنا تطابق النتائج التي سيراها خط أنابيب البناء.
  • ثلاثة أوضاع ناتج تغطي المستهلكين النهائيين الشائعين: القيم الخام للنسخ واللصق، والمسارات لتصحيح تحليل المحرك، ومؤشرات RFC 6901 Pointers لسير عمل JSON Patch ومخطط JSON.
  • تعبيرات التصفية تُشغَّل بـ preventEval: true، فاستعلام مُلصَق لا يستطيع تنفيذ JavaScript عشوائي على صفحة المضيف. هذا مهم حين جاء التعبير من رسالة Slack أو تذكرة Jira أو حافظة زميل.

التطبيقات الشائعة لـ JSONPath

يظهر JSONPath في كل مكان يجب فيه على الشيفرة سحب حقل من حمولة JSON دون كتابة نزول تكراري يدوي:

  • اختبارات Postman: تبويب Tests في Postman يُعرّض pm.response.json() مع وصول بأسلوب JSONPath للتأكيدات. تكتب الفرق تعبيراً واحداً كـ $.data.user.email لسحب حقل من استجابة والتأكيد عليه في CI.
  • اختبارات الحمل k6: سكريبتات k6 تستدعي jsonpath() داخل كتلة check() لاستخراج القيم من أجسام الاستجابة والتأكيد على حدود SLA. التعبير ذاته الذي أثبت عقداً في Postman يستطيع تقييد اختبار حمل في k6.
  • DSL لتحويلات البيانات: AWS Step Functions يُقيِّم JSONPath داخل InputPath وResultPath وParameters لإعادة تشكيل حمولات الأحداث بين الحالات. Argo Workflows يستخدم JSONPath في withParam لتوزيع المهام على مصفوفة. kubectl -o jsonpath من Kubernetes يستخدم الصياغة ذاتها لاستخراج الحقول من كائنات الكتلة.

مثال عملي

التركيبة الكلاسيكية لـ Goessner هي مستند متجر الكتب بأربعة كتب، كل منها يحمل category وauthor وtitle وprice. مقابل تلك التركيبة، يُشغَّل التعبير $.store.book[?(@.price<10)].title في ثلاث خطوات. أولاً، يُحلّ $.store.book إلى مصفوفة الكتب الأربعة. ثانياً، تُبقي التصفية [?(@.price<10)] الكتاب الواحد الذي سعره أقل من 10 فقط. أخيراً، يستخرج .title عنوان ذلك الكتاب. النتيجة ["Sayings of the Century"]. التبديل إلى المسارات يُرجع ["$['store']['book'][0]['title']"]، والمؤشرات تُرجع ["/store/book/0/title"].

صمِّم تعبيراتك هنا، ثم أدرجها مباشرةً في Postman أو k6 أو kubectl أو آلة حالة Step Functions. الصق، واستعلم، وانسخ. لا شيء يعبر الشبكة.

ما هو JSONPath؟

JSONPath هو لغة استعلام لمستندات JSON، بالقياس إلى XPath لـ XML. اقترحه Stefan Goessner عام 2007 وقنّنته IETF بـ RFC 9535 عام 2024، ويستخدم صياغة تعبير مدمجة تبدأ بـ $ (جذر المستند) وتدعم التدوين النقطي ومقادير المصفوفات والبدلات والشرائح والنزول التكراري (..) وتعبيرات التصفية ([?(...)]) لتحديد العقد داخل شجرة JSON.

كيف يختلف JSONPath عن JMESPath أو jq؟

الثلاثة تستعلم JSON، لكن قواعدها النحوية وأهدافها تختلف. JMESPath هو معيار AWS CLI/SDK: أكثر صرامةً من JSONPath، ولا نزول تكراري، مبني للإسقاط المتوقع خالي من الآثار الجانبية. jq هو لغة تتمتع بالكمال الحسابي لا تستعلم JSON فحسب بل تحوّله وتختزله وتُدفقه. JSONPath يقع بينهما: أكثر تعبيراً من JMESPath بفضل النزول التكراري والتصفيات، وأخف من jq، وأكثر الصياغات دعماً في أدوات الاختبار العامة (Postman وPlaywright وREST Assured وkubectl وStep Functions). هذا المُختبر يُطبّق JSONPath.

ما اللهجة التي يستخدمها هذا المُختبر؟

يُشغِّل هذا المُختبر jsonpath-plus 9.x. تلك المكتبة تُطبّق مواصفة Goessner 2007، وتغطي معظم RFC 9535، وتُضيف عوامل امتداد كالتحقق من الأنواع (@.string()، @.number()، @.boolean()) والتنقل للوالد (^). علم preventEval: true مُضبوط دائماً، فمحمولات التصفية تُشغَّل عبر مُفسِّر آمن بدلاً من الدالة المدمجة eval(). استعلام مُلصَق لا يستطيع تنفيذ كود عشوائي على هذه الصفحة.

هل يمكنني نسخ قيم مُطابَقة فردية؟

نعم. زر نسخ إلى الحافظة ينسخ كتلة النتيجة كاملةً كمصفوفة JSON. للإمساك بقيمة واحدة، بدّل وضع الناتج إلى القيم، ثم حدد السطر الذي تريده في حقل نص النتيجة واستخدم اختصار النسخ العادي في متصفحك (Ctrl/Cmd + C). الناتج نص JSON عادي، فيُلصق بنظافة في محرر شيفرة أو طرفية أو اختبار Postman أو رسالة Slack.