כלי השוואת JSON - השווה JSON באינטרנט בחינם | הבדלי JSON
השווה JSON באינטרנט בחינם עם כלי ההשוואה המהיר שלנו. מצא הבדלים מיידית עם תוצאות בצבעים. השוואת JSON דרך הדפדפן ב-100% אבטחה. ללא הרשמה נדרשת.
כלי השוואת JSON
תיעוד
כלי להשוואת JSON, המכונה לעיתים קרובות כלי diff ל־JSON, משווה בין שני ערכי JSON (סימון אובייקטים של JavaScript) ומדווח מה השתנה ביניהם. הוא מציג כל מאפיין או איבר מערך שנוסף, הוסר או שונה, יחד עם מיקומו המדויק בנתונים. דף זה מסביר כיצד פועל כלי השוואת ה־JSON של whiz.tools, באמצעות דוגמאות פתורות המבוססות על לוגיקת ההשוואה בפועל שלו.
מהי השוואת JSON?
השוואת JSON היא תהליך של בדיקת שני מסמכי JSON זה מול זה כדי למצוא הבדלים. מסמך JSON הוא פיסת טקסט הבנויה מאובייקטים (צמדי מפתח־ערך בתוך סוגריים מסולסלים), מערכים (רשימות מסודרות בתוך סוגריים מרובעים) וערכים פרימיטיביים כגון מחרוזות, מספרים, ערכים בוליאניים ו־null. השוואה ידנית של שני מסמכים כאלה נעשית איטית ונוטה לשגיאות לאחר שהם גדלים מעבר לכמה שורות, ולכן כלי השוואה מבצע את ההתאמה באופן אוטומטי ומדגיש כל שינוי.
מפתחים משתמשים בהשוואה מסוג זה כדי לבדוק תגובות API, לעקוב אחר שינויים בקובצי תצורה, לוודא שהעברת נתונים לא גרמה לאובדן מידע ולסקור שינויים בקובצי JSON במערכת בקרת גרסאות.
כיצד הכלי משווה בין שני ערכי JSON
הכלי מנתח את שני הקלטים באמצעות מנתח JSON תקני, ואז עובר על שני הערכים שנוצרו יחד, רמה אחר רמה. בכל שלב הוא שואל שלוש שאלות, לפי הסדר:
- האם לשני הערכים יש טיפוסים שונים (לדוגמה, האחד הוא אובייקט והאחר מספר), או שהאחד הוא
nullבעוד האחר אינו כזה? אם כן, הוא מתעד שינוי במקום זה ומפסיק להשוות ברמות עמוקות יותר. - האם שני הערכים הם פרימיטיביים (מחרוזת, מספר, ערך בוליאני או null)? אם כן, הוא משווה ביניהם ישירות. כל הבדל, כולל שינוי מהמספר
123למחרוזת"123", נחשב לשינוי. - האם שני הערכים הם אובייקטים או ששניהם מערכים? אם כן, הוא משווה את התוכן שלהם לפי הכללים שלהלן ומבצע קריאה רקורסיבית עבור כל אובייקט או מערך מקונן.
כל הבדל מתועד עם נתיב, כגון user.address.city או tags[1], כדי שיהיה קל למצוא אותו במסמך המקורי. איברי אובייקט מחוברים בנקודה, ואיברי מערך מוצגים באמצעות האינדקס שלהם בתוך סוגריים מרובעים. להבדל בראש המסמך, כגון החלפת מערך באובייקט, אין נתיב בתוך הנתונים, ולכן הוא מסומן באמצעות $. זהו מזהה השורש המוגדר ב־RFC 9535, תקן JSONPath, והוא מייצג את המסמך כולו.
השוואת אובייקטים
עבור שני אובייקטי JSON, הכלי אוסף כל מפתח שמופיע באחד מהאובייקטים או בשניהם. עבור כל מפתח:
- אם המפתח קיים רק באובייקט השני, זהו מאפיין שנוסף.
- אם המפתח קיים רק באובייקט הראשון, זהו מאפיין שהוסר.
- אם המפתח קיים בשניהם, הכלי משווה בין שני הערכים באופן רקורסיבי.
סדר המפתחות אינו משנה. תקן JSON אינו מגדיר סדר לאיברי אובייקט, ולכן {"a":1,"b":2} ו־{"b":2,"a":1} נחשבים זהים.
השוואת מערכים
מערכים מושווים לפי מיקום, ולא לפי תוכן. הכלי עובר על שני המערכים אינדקס אחר אינדקס ומשווה את מה שנמצא בכל אינדקס, עד לאורך המערך הארוך יותר. אם מערך אחד קצר יותר, האיברים הנוספים בסוף המערך הארוך יותר מדווחים כפריטים שנוספו או הוסרו.
פירוש הדבר שהכלי לעולם אינו מנסה להתאים איברי מערך לפי התוכן שלהם. הוא אינו מזהה שאובייקט "הועבר" מאינדקס 1 לאינדקס 2; הוא רואה רק שהערך בכל אינדקס השתנה. מחיקה או הוספה של איבר באמצע מערך מזיזה את כל האיברים שאחריו במיקום אחד, ולכן בדרך כלל היא מופיעה כמספר שינויים נפרדים ולא כהוספה או הסרה יחידה וברורה.
דוגמה פתורה
דוגמה 1: השוואת שני אובייקטים
JSON ראשון:
1{ "user": { "address": { "city": "New York", "zip": "10001" } } }
2JSON שני:
1{ "user": { "address": { "city": "Boston", "zip": "02108" } } }
2תוצאה:
- שינוי ב־
user.address.city:"New York"→"Boston" - שינוי ב־
user.address.zip:"10001"→"02108"
דוגמה 2: שינוי במערך בסופו
JSON ראשון:
1{ "tags": ["important", "urgent", "review"] }
2JSON שני:
1{ "tags": ["important", "critical", "review", "documentation"] }
2אינדקס 0 לא השתנה, אינדקס 1 השתנה, אינדקס 2 לא השתנה, ואינדקס 3 קיים רק במערך השני. תוצאה:
- שינוי ב־
tags[1]:"urgent"→"critical" - נוסף
tags[3]:"documentation"
דוגמה 3: הסרת איבר מאמצע מערך
דוגמה זו מראה מה קורה כאשר איבר מוסר מאמצע מערך, משום שזהו מקור נפוץ לבלבול.
JSON ראשון:
1{
2 "products": [
3 { "id": 1, "name": "Laptop", "price": 999.99 },
4 { "id": 2, "name": "Mouse", "price": 24.99 },
5 { "id": 3, "name": "Keyboard", "price": 59.99 }
6 ]
7}
8JSON שני, כאשר הרשומה "Mouse" נמחקה ונוספה רשומת "Monitor" בסוף:
1{
2 "products": [
3 { "id": 1, "name": "Laptop", "price": 899.99 },
4 { "id": 3, "name": "Keyboard", "price": 59.99 },
5 { "id": 4, "name": "Monitor", "price": 349.99 }
6 ]
7}
8אדם המתבונן בכך היה אומר: "Mouse הוסר ו־Monitor נוסף." מכיוון שהכלי משווה אך ורק לפי אינדקס, הוא אינו רואה זאת כך. הוא משווה את אינדקס 0 לאינדקס 0, את אינדקס 1 לאינדקס 1 ואת אינדקס 2 לאינדקס 2, ולכן כל שדה שלאחר האיבר שנמחק מותאם לאובייקט שגוי. התוצאה בפועל היא שבעה שינויים:
- שינוי ב־
products[0].price:999.99→899.99 - שינוי ב־
products[1].id:2→3 - שינוי ב־
products[1].name:"Mouse"→"Keyboard" - שינוי ב־
products[1].price:24.99→59.99 - שינוי ב־
products[2].id:3→4 - שינוי ב־
products[2].name:"Keyboard"→"Monitor" - שינוי ב־
products[2].price:59.99→349.99
כדי לקבל תוצאה ברורה יותר בעת השוואת רשימות כאלה, יש למיין את שני המערכים או ליצור להם מפתחות באותה דרך לפני הדבקתם, למשל על ידי כתיבת כל רשימה באותו סדר או התאמת האובייקטים לפי שדה מזהה לפני ההשוואה.
מה הכלי אינו עושה
- הוא אינו מתאים איברי מערך לפי תוכן. כפי שהודגם לעיל, הוא משווה אך ורק לפי מיקום האינדקס, ולכן אינו יכול לזהות שאיבר הועבר ולא השתנה.
- הוא אינו מזהה הפניות מעגליות. בפועל אין לכך מגבלה: שני הקלטים מגיעים מ־
JSON.parse, שבונה תמיד עץ פשוט ולעולם אינו יכול ליצור ערך המפנה חזרה לעצמו. הפניות מעגליות אינן יכולות להופיע בטקסט JSON תקף מלכתחילה. - הוא אינו מציע הגדרה למיון מערכים לפני ההשוואה. סידור מחדש של האיברים בקלט לפני הדבקתם הוא הדרך היחידה להימנע מהשפעת שינויי האינדקס שתוארה לעיל.
כיצד להשתמש בכלי
- יש להדביק את מסמך ה־JSON הראשון בתיבה השמאלית ואת השני בתיבה הימנית.
- הכלי משווה ביניהם באופן אוטומטי לאחר ששתי התיבות מכילות טקסט, או שאפשר ללחוץ על Compare כדי להפעיל את ההשוואה ידנית.
- יש לקרוא את רשימת התוצאות. כל שורה מציגה נתיב, כגון
user.age, ומציינת אם הוא נוסף, הוסר או שונה, כאשר הערכים הישן והחדש מוצגים זה לצד זה. - יש ללחוץ על Copy כדי להעתיק את התוצאות כטקסט פשוט.
אם תיבה מכילה טקסט שאינו JSON תקף, הכלי מציג שגיאה מתחת לתיבה במקום השוואה. כאשר שתי התיבות אינן תקפות, שתי השגיאות מופיעות בו־זמנית.
שאלות נפוצות
מה נחשב להבדל בין שני ערכי JSON?
מאפיין או איבר מערך נחשב שונה אם הוא קיים רק באחד משני המסמכים, או אם הוא קיים בשניהם אך מכיל ערך שונה או טיפוס שונה. שינוי ערך מהמספר 5 למחרוזת "5" נחשב לשינוי, אף שהם עשויים להיראות דומים.
האם סדר האיברים משנה? הדבר תלוי במבנה המכיל. לאובייקטי JSON אין סדר איברים מוגדר, ולכן שני אובייקטים בעלי אותם מפתחות וערכים בסדר שונה נחשבים זהים. מערכים הם מסודרים, והכלי משווה אותם לפי מיקום האינדקס, ולכן העברת איבר למיקום אחר מדווחת כסדרה של שינויים ולא כהעברה.
מה פירוש נתיב תוצאה $?
פירוש הדבר שהמסמך כולו השתנה, ולא רק חלק ממנו. הדבר קורה כאשר שני הקלטים הם ערכים מסוגים שונים ברמה העליונה, למשל מערך בצד אחד ואובייקט בצד האחר, או המספרים הפשוטים 1 ו־2. $ הוא מזהה השורש מ־RFC 9535, תקן JSONPath.
האם נתוני ה־JSON שלי נשלחים לשרת? לא. ההשוואה מתבצעת בדפדפן באמצעות JavaScript. שום דבר אינו מועלה.
האם עיצוב, כגון הזחה או מזעור, משפיע על התוצאה? לא. שני הקלטים מנותחים לערכי JSON לפני ההשוואה, ולכן רווחים לבנים, הזחה ומעברי שורה אינם משנים דבר. רק הנתונים עצמם מושווים.
האם הכלי יכול להשוות JSON עם הערות או פסיקים מיותרים בסוף? לא. JSON תקני, כפי שהוגדר ב־RFC 8259, אינו מאפשר הערות או פסיקים מיותרים בסוף. קלט המכיל אותם נדחה כלא תקף.
מקורות
- IETF. "תבנית חילופי הנתונים JavaScript Object Notation (JSON)." RFC 8259, דצמבר 2017.
- IETF. "תיקון JavaScript Object Notation (JSON)." RFC 6902, אפריל 2013.
- IETF. "JSONPath: ביטויי שאילתה עבור JSON." RFC 9535, פברואר 2024. (סעיף 2.2 מגדיר את מזהה השורש
$.) - רשת המפתחים של מוזילה. "JSON.parse()."