guide/json-diff.md

كيف تقارن JSON — ترتيب المفاتيح والتوحيد

كيف تتخلص من الفروق الزائفة الناتجة عن ترتيب المفاتيح والمسافات البادئة وطريقة كتابة الأرقام عند مقارنة ملفي JSON، مع شرح ترتيب المصفوفات والأعداد الصحيحة الكبيرة والفرق عن JSON Patch.

آخر تحديث: 2026-09-23

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

لماذا تظهر فروق زائفة؟

يعرّف معيار JSON ‏(RFC 8259) الكائن بأنه «مجموعة غير مرتبة من أزواج الاسم/القيمة». أي أن {"a":1,"b":2} و{"b":2,"a":1} يمثلان البيانات نفسها. لكن ترتيب الأسطر في النص مختلف، فيعدّه diff فرقًا. وإضافة إلى ذلك تنشأ الفروق التالية دون علاقة بالبيانات:

الحل: التحليل ثم إعادة الكتابة بالشكل نفسه

الطريقة الأضمن هي تحليل ملفي JSON إلى بيانات ثم إعادة تسلسلهما بالقواعد نفسها.

  1. حلّل النصين كـ JSON. إن وُجد خطأ في الصياغة فأصلحه أولًا.
  2. رتّب مفاتيح جميع الكائنات تكراريًا.
  3. أعد الكتابة بالمسافة البادئة نفسها (مثل مسافتين).
  4. قارن النتيجة سطرًا بسطر.

على سبيل المثال، يختلف ملفا JSON التاليان في ترتيب المفاتيح وفي ترتيب عناصر المصفوفة.

{"name":"kim","age":30,"tags":["a","b"]}
{"age":30,"name":"kim","tags":["b","a"]}

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

@@ -2,7 +2,7 @@   "age": 30,   "name": "kim",   "tags": [-    "a",-    "b"+    "b",+    "a"   ] }

لا تُرتَّب المصفوفات

على عكس الكائنات، للترتيب في المصفوفات معنى. ["a","b"] و["b","a"] بيانات مختلفة. لذلك فالأصل ألا تُرتَّب المصفوفات عند التوحيد. لكن إذا كانت المصفوفة مثل قائمة الوسوم لا يهم ترتيبها في العمل، فإن ترتيبها يدويًا قبل المقارنة يجعل النتيجة أسهل قراءة. أيّ الأمرين هو الصحيح يتوقف على معنى البيانات.

ما الذي يغيّره التحليل؟

لطريقة التحليل ثم إعادة الكتابة آثار جانبية يجب معرفتها.

الطريقة من سطر الأوامر

إذا كانت أداة jq مثبتة فيمكنك باستخدام الخيار -S ‏(--sort-keys) إخراج JSON بمفاتيح مرتبة.

jq -S . before.json > a.json
jq -S . after.json  > b.json
diff -u a.json b.json

الفرق عن JSON Patch

نتيجة diff قائمة تغييرات على مستوى السطر موجّهة للقراءة البشرية. أما JSON Patch ‏(RFC 6902) فمعيار يعبّر عن التغييرات بمسارات داخل بنية JSON، مثل {"op":"replace","path":"/age","value":31}، وJSON Merge Patch ‏(RFC 7396) طريقة تُطبّق على الأصل JSON يحتوي على الأجزاء المتغيرة فقط. إذا كانت البرامج تتبادل التغييرات فيما بينها فهذه المعايير هي الأنسب، وإذا كان الإنسان هو من يراجع فالأنسب diff نصي بعد الترتيب.

جرّبها في هذه الأداة

إذا فعّلت خيار ترتيب مفاتيح JSON في مقارنة النصوص، يُحلَّل الجانبان وتُرتَّب المفاتيح ويُعاد الكتابة بمسافة بادئة من مسافتين ثم تجري المقارنة. لا يتغير ترتيب المصفوفات، وإذا فشل التحليل تخبرك الأداة في أي جهة وعند أي حرف وقع الخطأ. يمكنك أيضًا سحب ملفي .json وإفلاتهما معًا. ولقراءة النتيجة كـ patch راجع مقال كيف تقرأ unified diff.

انتقل إلى مقارنة النصوص