يعد JSON حاليًا أحد أهم التنسيقات لتبادل البيانات بين التطبيقات، خاصة عبر الإنترنت. JSONPath هي لغة تعبير يمكن استخدامها لقراءة بيانات محددة من كائنات JSON. هنا، سنلقي نظرة على تنفيذ Python لـ JSONPath ومكان استخدامه باستخدام أمثلة سهلة الفهم.
ما هو بايثون JSONPath؟¶
JSON هو تنسيق ملف مشترك بين الأنظمة يمكن استخدامه لتسهيل تبادل البيانات المنظمة بين التطبيقات. ملفات جيسون تتكون من أزواج القيمة الرئيسية المدرجة. يمكن أن تقبل القيم أنواعًا مختلفة من البيانات، سواء القيم الأولية أو الكائنات. الكائنات، بدورها، يمكن أن تحتوي على أزواج قيمة المفتاح الخاصة بها. نظرًا لأن JSON مفهومة من قبل جميع الأنظمة الحديثة تقريبًا، فيمكن استخدامه لتبادل البيانات بين أي نوع من التطبيقات، سواء محليًا على الجهاز أو عبر الإنترنت.
ولكن ليس كل تطبيق يحتاج إلى جميع بياناته التي تم التقاطها في ملف JSON. في هذه الحالات، يعد JSONPath خيارًا جيدًا. JSONPath هي لغة تعبير يمكن استخدامها قراءة معلومات محددة من كائنات JSON. في معظم لغات البرمجة، يجب استيراد JSONPath من مكتبة خارجية. ونظرًا لأنه يجب تنفيذ هذه المكتبات بشكل منفصل لكل لغة، فقد تختلف المكتبات أو عمليات التنفيذ قليلاً.
وحدة بايثون jsonpath-ng¶
jsonpath-ng
ربما يكون تطبيق Python الأكثر شيوعًا لـ JSONPath. هناك أيضًا تطبيقات JSONPath أخرى لـ Python، مثل jsonpath
و jsonpath-rw
. لكن هذه أقل شعبية وشمولية، لذلك سنركز عليها حصريًا jsonpath-ng
هنا.
تثبيت¶
يمكنك التثبيت jsonpath-ng
بسهولة جدا من قوقعتك. ببساطة أدخل الأمر pip install jsonpath-ng
للبدأ.
التثبيت يتم عبر نقطة مدير الحزم، والذي يُستخدم بشكل افتراضي لـ Python. في حالة عدم تثبيت مدير الحزم هذا، فستحتاج إلى تنزيله أولاً. يمكن العثور على مزيد من المعلومات على موقع Pip.
بناء الجملة¶
يمكن استخدام JSONPath لتنفيذ استعلامات معقدة على كائنات JSON. هناك العديد من الطرق وعوامل التشغيل والتعبيرات الذرية في الوحدة التي يمكن استخدامها لتحديد بيانات محددة والاستعلام عنها. أهم طريقتين JSONPath هما parse()
و find()
. مع parse()
أنت تستطيع تحديد الاستعلامات، والتي يمكن بعد ذلك الرجوع إليها وتكرارها بقدر ما تريد. مع find()
يمكنك تشغيل هذه الاستعلامات على بيانات JSON استخراج القيم المحددة. والمثال التالي يوضح ذلك أكثر.
import json
import jsonpath_ng as jp
raw_data=""'
{
"name": "John",
"age": 30,
"place of residence": "New York"
}
'''
json_object = json.loads(raw_data)
name_query = jp.parse("$.name")
result = name_query.find(json_object)
print(result[0].value) # output: John
بايثون
في المثال أعلاه، تم تحويل بيانات JSON في شكل سلسلة إلى ملف كائن القاموس استخدام json.loads
. هذا هو التنسيق الذي تعمل معه بايثون بشكل أفضل. عند الإنشاء name_query
، الطلب $.name
تم تعريفه، والذي يجب أن يُرجع قيمة name
. ثم تم تطبيق ذلك على كائن JSON باستخدام find()
. تم تخزين نتيجة الطلب في المتغير result
واقرأ مع result[0].value
.
لكي تتمكن بايثون من قراءة بيانات JSON من سلسلة أو من ملف JSON، استخدم وحدة Python json
يجب أن يتم تضمينها، كما في المثال أعلاه. يمكن بعد ذلك تحويل السلاسل والملفات إلى تنسيق يمكن قراءته باستخدام Python loads()
أو load()
.
لا تقوم طريقة البحث بإرجاع القيمة المطلوبة فحسب، بل أيضًا معلومات سياقية أخرى، مثل المسار إلى القيمة التي تم البحث عنها. يتم إرجاع هذه المعلومات في شكل قائمة، حيث تحتوي القيمة التي تبحث عنها على فهرس 0. الآن يمكنك استخدام result[0].value
لإخراج القيمة التي تبحث عنها.
في المثال أعلاه، تم استخدام علامة الدولار عند إعداد الطلب. هذا التعبير الذري الذي يستخدم للإشارة إلى جذر كائن JSON. يتم سرد كافة العوامل والتعبيرات الذرية في الجدول التالي.
التعبير/المشغل | معنى | مثال | توضيح |
---|---|---|---|
$
|
كائن الجذر | $.marcus.age
|
يبحث عن قيمة مفتاح “العمر” من كائن “ماركوس”. |
.
|
مجال الكائن | $.marcus
|
يبحث عن “marcus”، حيث “marcus” هو حقل للكائن الجذر. |
..
|
البحث العودي عن الحقل. يتم أيضًا البحث في الحقول الموجودة في الكائنات الفرعية. | $.people..age
|
إرجاع كافة تكرارات حقل “العمر” في الأشخاص وكائناته الفرعية. |
[x]
|
عنصر في مصفوفة | $.people[5]
|
يبحث في العنصر السادس (في الفهرس 5) في مصفوفة “الأشخاص”. |
\*
|
العنصر النائب للأرقام، يُستخدم غالبًا فيما يتعلق بحلقات for | ‘$.الناس[*]’ | يبحث في حقل في “الناس”. بالاشتراك مع حلقة for، يتم إرجاع كل حقل بدوره. |
بالإضافة إلى التعبيرات وعوامل التشغيل، هناك المرشحات التي يمكنك استخدامها لجعل بحثك أكثر تحديدًا. في تطبيق Python لـ JSONPath، يمكن تنفيذها باستخدام مشغلي Python. يتم عرض كافة الرموز التي يمكن استخدامها مع المرشحات مع الأمثلة في الجدول التالي.
حرف او رمز | معنى | مثال | توضيح |
---|---|---|---|
.[?(filter) ]
|
بناء الجملة العام للمرشحات. يمكن استبعاد الأقواس المستديرة. | $.people[?(@.name == "Anne")]
|
يبحث عن الأشخاص الذين اسمهم “آن”. |
@
|
الكائن الذي يتم البحث عنه حاليًا، والذي يُستخدم غالبًا فيما يتعلق بحلقات for. | $.people[?(@.age < 50)]
|
يبحث في الحقول في “الأشخاص” الذين تقل قيمة “العمر” عن 50. |
< , > , <= , >= , == و !=
|
عوامل المقارنة التي يمكن استخدامها لتصفية نتائج بحث محددة. | $.people[@.age < 50 & @.age > 20]
|
البحث عن الأشخاص الذين تتراوح أعمارهم بين 20 و50 عامًا. |
&
|
منطقي و. | $.people[?(@.place of residence == Newark & @.age > 40)]
|
يبحث عن الأشخاص الذين تزيد أعمارهم عن 40 عامًا ويعيشون في نيوارك. |
إذا كنت ترغب في استخدام المرشحات، فأنت بحاجة إلى تضمين الوحدة النمطية jsonpath_ng.ext
والرجوع إليه عند الاتصال parse()
.
حالة الاستخدام لـ Python JSONPath¶
import json
import jsonpath_ng as jp
import json
import jsonpath_ng as jp
# JSON data as string
data = """
{
"cities": [
{
"name": "Trenton",
"state": "New Jersey",
"residents": 90048,
"iscapital": true,
"neighborhood Central West": {
"residents": 1394
}
},
{
"name": "Hamburg",
"state": "Hamburg",
"residents": 1841000,
"iscapital": false
},
{
"name": "New York City",
"state": "New York",
"residents ": 8804190
"iscapital": false
},
{
"name": "Los Angeles",
"state": "California",
"residents": 3898767
}
]
}
"""
# Convert data from String to dictionary
json_data = json.loads(data)
# Inquiry: Names of all cities
query1 = jp.parse("cities[*].name")
for match in query1.find(json_data):
print(match.value) # output: Trenton, Hamburg, New York City, Los Angeles
# jsonpath_ng.ext import to apply filters
import jsonpath_ng.ext as jpx
# Anfrage: Names of all cities with less than 1.5 million residents
query2 = jpx.parse("$.cities[?@.residents < 1500000].name")
for match in query2.find(json_data):
print(match.value) # output: Trenton
# All fields labeled “residents”
query3 = jp.parse("$.cities..residents")
match = query3.find(json_data)
for i in match:
print(i.value) # output: 1394, 1841000, 8804190, 3898767
# The names of all cities that are not called “Trenton”
query4 = jpx.parse('$.cities[?(@.name != "Trenton")].name')
for match in query4.find(json_data):
print(match.value) # output: Hamburg, New York City, Los Angeles
بايثون
في هذا المثال، يتم تحديد بيانات JSON كسلسلة ثم يتم تحويلها إلى كائن قاموس باستخدام loads()
. لا يوجد سوى مصفوفة واحدة في الكائن الجذر، والتي تحتوي بدورها على 4 مدن. تحتوي كل مدينة على 4 حقول تحتوي على البيانات التالية:
- اسم المدينة
- حالة المدينة
- عدد السكان
- سواء كانت المدينة هي العاصمة أم لا
يوجد في نيوجيرسي حقل إضافي يسمى “الغرب الأوسط” والذي يضم أيضًا عددًا من السكان.
بعد تحويل البيانات إلى تنسيق مناسب، يتم تنفيذ 4 استعلامات مختلفة. ويتم ترك وظائفها ومخرجاتها كتعليقات في المثال. قد تلاحظ أن خمس قيم عادت في الطلب الثالث. وذلك لأن عامل التشغيل “..” يبحث بشكل متكرر عن الحقول المطابقة. وهذا يعني أنه يتم البحث في كافة الكائنات، بالإضافة إلى كافة العناصر التابعة لهذه الكائنات. وعليه، يتم إدراج عدد سكان المنطقة الوسطى الغربية بجانب عدد سكان المدن.
معًا، يعد JSON وPython أداة متعددة الاستخدامات لبرمجة الإنترنت. إذا كان لديك تطبيق ويب تريد نشره بسرعة وسهولة ومباشرة من Git، فقد يكون النشر الآن من IONOS هو الحل الأمثل.
اكتشاف المزيد من إشراق العالم
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.