ไวยากรณ์ JSON อนุญาตคีย์ที่ซ้ำกันในวัตถุหรือไม่


205

json นี้ถูกต้องหรือไม่

{
    "a" : "x",
    "a" : "y"
}

http://jsonlint.com/พูดว่าใช่

http://www.json.org/ไม่พูดอะไรเกี่ยวกับเรื่องนี้ว่าเป็นสิ่งต้องห้าม

แต่เห็นได้ชัดว่ามันไม่เข้าท่าใช่มั้ย การใช้งานส่วนใหญ่อาจใช้ hashtable ดังนั้นมันจึงถูก overriden ต่อไป


1
Json.NET ของ C # จะลบคู่คีย์แรกถ้าคุณหมดสิทธิ์ในการDictionary<string, string>
Sam Leach

ในกรณีที่ทุกคนมาถึงที่นี่โดยหวังว่าจะหาวิธีแก้ปัญหาเพื่อค้นหาค่าที่ซ้ำกันในสตริง JSON ลองใช้ตัวตรวจสอบความถูกต้อง json ออนไลน์
Pepijn Olivier

jsonlint.comพูดว่าใช่ มันไม่ได้ลบทั้งหมด แต่คู่คีย์ - ค่าสุดท้ายจากนั้นตรวจสอบมันซึ่งทำให้มันถูกต้อง
Tim

7
จากนั้นมาตรฐานก็ถูกทำลาย
แบรดโทมัส

1
ฉันใช้ชื่อคีย์ "-" เป็นผู้วิจารณ์และค่าเป็นสายอักขระบรรทัดเดียวเป็นความคิดเห็น ดังนั้นฉันหวังว่าจะไม่มีตัวแยกวิเคราะห์ที่จะบ่นเกี่ยวกับเรื่องนี้
Lothar

คำตอบ:


126

จากมาตรฐาน (หน้า ii) :

คาดว่ามาตรฐานอื่นจะอ้างอิงถึงสิ่งนี้โดยยึดตามรูปแบบข้อความ JSON อย่างเคร่งครัดขณะที่กำหนดข้อ จำกัด ในรายละเอียดการเข้ารหัสต่างๆ มาตรฐานดังกล่าวอาจต้องการพฤติกรรมที่เฉพาะเจาะจง JSON เองไม่ได้ระบุพฤติกรรม

ยิ่งลงไปในมาตรฐาน (หน้า 2) สเปคสำหรับวัตถุ JSON:

โครงสร้างวัตถุถูกแสดงเป็นคู่ของโทเค็นวงเล็บปีกกาที่ล้อมรอบคู่ชื่อ / ค่าเป็นศูนย์หรือมากกว่า ชื่อคือสตริง โทเค็นโคลอนเดี่ยวติดตามแต่ละชื่อโดยแยกชื่อออกจากค่า โทเค็นเครื่องหมายจุลภาคเดียวคั่นค่าจากชื่อต่อไปนี้

ไดอะแกรมสำหรับวัตถุ JSON

ไม่ได้กล่าวถึงคีย์ที่ซ้ำกันว่าไม่ถูกต้องหรือไม่ถูกต้องดังนั้นตามข้อกำหนดที่ฉันจะถือว่าปลอดภัยหมายความว่าพวกเขาได้รับอนุญาต

การปรับใช้ส่วนใหญ่ของไลบรารี JSON ไม่ยอมรับคีย์ที่ซ้ำกันจะไม่ขัดแย้งกับมาตรฐานเนื่องจากการอ้างอิงครั้งแรก

นี่คือสองตัวอย่างที่เกี่ยวข้องกับไลบรารีมาตรฐาน C ++ เมื่อทำการแยกวัตถุ JSON ออกเป็นวัตถุstd::mapจะทำให้การปฏิเสธคีย์ที่ซ้ำกัน แต่เมื่อทำการแยกวัตถุ JSON บางส่วนออกเป็นสิ่งที่เหมาะสมstd::multimapก็คือการยอมรับคีย์ที่ซ้ำกันตามปกติ


5
ฉันเดาว่าฉันสามารถยอมรับสิ่งนี้เป็นคำตอบได้ แต่ฉันชอบพูดถึง @PatrickGoley ที่ json.org เรียกว่าชุดของคีย์ / ค่า - คู่ซึ่งแสดงถึงความเป็นเอกลักษณ์ซึ่งหมายความว่ามันไม่ถูกต้อง
หนีบ

8
@clamp json.org ไม่ใช่มาตรฐานและเท่าที่ฉันสามารถบอกได้ว่าไม่ได้ดำเนินการโดย Emca International ดูเหมือนว่า json.org จะถูกนำเสนอโดยไม่ระบุชื่อ นี่คือสเปค: ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdfสิ่งที่กล่าวใน json.org ไม่เกี่ยวข้อง
Timothy Shields

5
@clamp ลองพิจารณาstd::multimapตัวอย่างที่เพิ่งเพิ่มเข้าไป มันสามารถต่อเนื่องเป็นวัตถุ JSON ด้วยคีย์ที่อาจซ้ำกัน
Timothy Shields

1
@clamp เป็นชุดคู่คีย์ / ค่าไม่ตัดชื่อซ้ำ {"a":1,"a":2}คือชุดของคู่คีย์ / ค่าที่แตกต่างกันสองคู่ ที่จริงแล้วแม้{"a":1,"a":1}จะคิดว่าเป็นชุดของคู่คีย์ / ค่าที่เกิดขึ้นมีเพียงองค์ประกอบเดียว ความจริงที่ว่ามันซ้ำแล้วซ้ำอีกสามารถคิดว่าเป็นเพียงการเล่นโวหารวากยสัมพันธ์ ความหมายที่ดีกว่าคือ "วัตถุคือฟังก์ชันบางส่วนจากสตริง (ชื่อ) ถึงค่า"
Marcelo Cantos

2
@TimothyShields และมาตรฐานที่คุณเชื่อมโยงกับพูดว่า "ไวยากรณ์ JSON ไม่ได้กำหนดข้อ จำกัด ใด ๆ ของสตริงที่ใช้เป็นชื่อไม่ต้องการให้ชื่อสตริงนั้นไม่ซ้ำกันและไม่ได้กำหนดความสำคัญใด ๆ กับการเรียงลำดับชื่อ / ค่าคู่"
Charles

135

คำตอบสั้น ๆ : ใช่ แต่ไม่แนะนำ
คำตอบที่ยาวนาน: ขึ้นอยู่กับสิ่งที่คุณเรียกว่าถูกต้อง ...


ECMA-404 "ไวยากรณ์การแลกเปลี่ยนข้อมูล JSON" ไม่ได้พูดอะไรเกี่ยวกับชื่อซ้ำ (คีย์)


อย่างไรก็ตามRFC 8259 "รูปแบบการแลกเปลี่ยนข้อมูลวัตถุ JavaScript (JSON)" กล่าวว่า:

ชื่อภายในวัตถุควรเป็นชื่อเฉพาะ

ในบริบทนี้ควรจะต้องเข้าใจตามที่ระบุในBCP 14 :

ควรคำนี้หรือคำคุณศัพท์ "แนะนำ" หมายความว่าอาจมีเหตุผลที่ถูกต้องในบางสถานการณ์ที่จะไม่สนใจรายการใดรายการหนึ่ง แต่ต้องเข้าใจและชั่งน้ำหนักอย่างรอบคอบก่อนเลือกหลักสูตรอื่น


RFC 8259อธิบายว่าทำไมชื่อเฉพาะ (คีย์) จึงดี:

วัตถุที่มีชื่อไม่ซ้ำกันสามารถใช้งานร่วมกันได้ในแง่ที่ว่าการใช้งานซอฟต์แวร์ทั้งหมดที่ได้รับวัตถุนั้นจะตกลงในการแมปชื่อ - ค่า เมื่อชื่อภายในวัตถุไม่ซ้ำกันพฤติกรรมของซอฟต์แวร์ที่ได้รับวัตถุดังกล่าวจะไม่สามารถคาดเดาได้ การใช้งานจำนวนมากรายงานคู่สุดท้ายของชื่อ / ค่าเท่านั้น การใช้งานอื่น ๆ รายงานข้อผิดพลาดหรือล้มเหลวในการแยกวิเคราะห์วัตถุและการใช้งานบางอย่างรายงานชื่อคู่ / ค่าทั้งหมดรวมถึงรายการที่ซ้ำกัน



นอกจากนี้ตามที่ Serguei ชี้ให้เห็นในความคิดเห็น: ECMA-262 "ข้อมูลจำเพาะภาษาECMAScript®" อ่าน:

ในกรณีที่มี Strings ชื่อซ้ำกันภายในวัตถุค่าก่อนหน้าของคำศัพท์สำหรับคีย์เดียวกันจะถูกเขียนทับ

ในคำอื่น ๆ มูลค่าสุดท้ายชนะ


การพยายามแยกสตริงที่มีชื่อซ้ำกับการใช้งาน Java โดย Douglas Crockford (ผู้สร้าง JSON) ส่งผลให้เกิดข้อยกเว้น :

org.json.JSONException: Duplicate key "status"  at
org.json.JSONObject.putOnce(JSONObject.java:1076)

1
JSON นั้นควรจะเป็นจาวาสคริปต์ที่ถูกต้องดังนั้นจึงเกี่ยวข้องกับการตรวจสอบว่าคีย์ที่ซ้ำกันนั้นเป็น JS ที่ถูกต้องหรือไม่ V8 ดูเหมือนจะยอมรับพวกเขา: d8 -e 'x={"a":1,"a":2}; print(x.a);'นี่พิมพ์ 2
เบ็นคราวเวล

5
นอกจากนี้ข้อมูลจำเพาะECMA-262สำหรับการJSON.parse()พูดอย่างชัดเจนIn the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.(ในคำอื่น ๆ ที่ผ่านมามูลค่า - ชนะ)
Serguei

4
@BenCrowell: เท่าที่ผมรู้ JSON ไม่ควรจะถูกต้อง JavaScript และมีกรณีที่ยังไม่ได้ดูtimelessrepo.com/json-isnt-a-javascript-subset แน่นอนว่ามันเป็นแรงบันดาลใจอย่างมากจากจาวาสคริปต์ (แม้จะกล่าวไว้ในข้อกำหนดของ JSON)
Simon Touchtech

2
เป็นที่น่าสังเกตว่าเมื่อใช้จาวาสคริปต์ "โหมดเข้มงวด" หากมีสองปุ่มที่เหมือนกันโครเมียมจะใช้คู่ของคีย์ - ค่าที่สองและละเว้นแรก IE11 จะส่งข้อยกเว้น
Shahar

18

มีเอกสาร 2 ฉบับที่ระบุรูปแบบ JSON:

  1. http://json.org/
  2. https://tools.ietf.org/html/rfc7159

คำพูดคำตอบที่ยอมรับได้จากเอกสารที่ 1 ฉันคิดว่าเอกสารฉบับที่ 1 มีความชัดเจนยิ่งขึ้น แต่เอกสารฉบับที่ 2 มีรายละเอียดเพิ่มเติม

เอกสารฉบับที่ 2 กล่าวว่า:

  1. วัตถุ

    โครงสร้างวัตถุถูกแสดงเป็นคู่ของวงเล็บปีกกาที่ล้อมรอบคู่ชื่อ / ค่าเป็นศูนย์หรือมากกว่า (หรือสมาชิก) ชื่อคือสตริง เครื่องหมายโคลอนเดียวมาหลังชื่อแต่ละชื่อแยกชื่อออกจากค่า เครื่องหมายจุลภาคเดียวคั่นค่าจากชื่อต่อไปนี้ ชื่อภายในวัตถุควรเป็นชื่อเฉพาะ

ดังนั้นจึงไม่ได้รับอนุญาตให้มีชื่อซ้ำกัน แต่มันเป็นสิ่งที่ท้อแท้


10

ฉันเจอคำถามที่คล้ายกันเมื่อจัดการกับ API ที่ยอมรับทั้ง XML และ JSON แต่ไม่มีเอกสารว่าจะจัดการกับสิ่งที่คุณคาดหวังว่าจะได้รับคีย์ซ้ำใน JSON ที่ยอมรับได้อย่างไร

ต่อไปนี้เป็นตัวแทน XML ที่ถูกต้องของตัวอย่าง JSON ของคุณ:

<object>
  <a>x</a>
  <a>y</a>
</object>

เมื่อสิ่งนี้ถูกแปลงเป็น JSON คุณจะได้รับสิ่งต่อไปนี้:

{
  "object": {
    "a": [
      "x",
      "y"
    ]
  }
}

การทำแผนที่ตามธรรมชาติจากภาษาที่จัดการกับสิ่งที่คุณอาจเรียกว่าคีย์ที่ซ้ำกันไปยังอีกสามารถใช้เป็นข้อมูลอ้างอิงการปฏิบัติที่ดีที่สุดที่นี่

หวังว่าจะช่วยใครบางคน!


5

ข้อมูลจำเพาะ JSON กล่าวว่า:

วัตถุคือชุดคู่ของชื่อ / ค่าที่ไม่เรียงลำดับ

ส่วนสำคัญที่นี่คือ "ไม่ได้เรียงลำดับ": มันหมายถึงเอกลักษณ์ของคีย์เพราะสิ่งเดียวที่คุณสามารถใช้เพื่ออ้างถึงคู่ที่เฉพาะเจาะจงคือกุญแจของมัน

นอกจากนี้ libs JSON ส่วนใหญ่จะทำการแยกวัตถุ JSON เพื่อแฮชแม็พ / พจนานุกรมที่มีการรับประกันคีย์ที่ไม่ซ้ำกัน จะเกิดอะไรขึ้นเมื่อคุณทำการเลิกวัตถุ JSON ที่มีคีย์ซ้ำกันขึ้นอยู่กับไลบรารี: ในกรณีส่วนใหญ่คุณจะได้รับข้อผิดพลาดหรือเฉพาะค่าสุดท้ายสำหรับแต่ละคีย์ที่ซ้ำกันเท่านั้นที่จะถูกนำมาพิจารณา

ยกตัวอย่างเช่นในหลามผลตอบแทนjson.loads('{"a": 1, "a": 2}'){"a": 2}


23
การไม่เรียงลำดับหมายความถึงความเป็นเอกลักษณ์หรือไม่? ฉันคิดว่าชุดเป็นคำผ่าตัดที่นี่
Patrick Goley

8
คอลเล็กชันสีที่ไม่มีการเรียงลำดับ: สีน้ำเงิน, เขียว, เขียว, น้ำเงิน, แดง, น้ำเงิน, เขียว - มันซ้ำซ้อน
Timothy Shields

5
วลีข้อความที่คุณอ้างถึง "วัตถุคือชุดคู่ของชื่อ / ค่าที่เรียงลำดับไว้" ไม่ปรากฏในข้อกำหนด JSON ...
Timothy Shields

6
ฉันเห็นแล้วว่าคุณกำลังอ้างถึง json.org มัน 'ใกล้' เป็นทางการ แต่ไม่ใช่สเปค ด้านบนของหน้ามีลิงก์ไปยังข้อมูลจำเพาะซึ่งทำซ้ำแบบคำต่อคำใน json.org หากคุณค้นหาข้อมูลจำเพาะคำว่า "unordered" จะไม่ปรากฏขึ้นและคำว่า "set" จะปรากฏในบริบทที่ไม่เกี่ยวข้องกับวัตถุ JSON เท่านั้น
Timothy Shields

5
โปรดทราบว่ามันระบุว่า "ชุดคู่ของชื่อ / คู่ค่าที่ไม่เรียงลำดับ" คู่ไม่ใช่ชื่อ นั่นคือ{ (a,b), (a,c) } เป็นชุดที่ไม่ซ้ำกัน ดังนั้นในทางเทคนิคภายใต้คำจำกัดความของ json.org {"a":1,"a":2}นั้นถูกต้อง แต่{"a":1,"a":2,"a":1}ไม่ใช่ โปรดทราบว่าECMA-404 (มาตรฐานจริง) หลีกเลี่ยงการใช้คำว่า "set":An object structure is represented as a pair of curly bracket tokens surrounding zero or more name/value pairs.
Serguei

3

ควรเป็นเอกลักษณ์ไม่ได้หมายความว่าจะต้องไม่ซ้ำกัน อย่างไรก็ตามตามที่ระบุไว้ตัวแยกวิเคราะห์บางตัวจะล้มเหลวและบางรายการก็ใช้ค่าสุดท้ายที่แยกวิเคราะห์ อย่างไรก็ตามถ้าข้อมูลจำเพาะถูกทำความสะอาดเล็กน้อยเพื่อให้สามารถทำซ้ำได้ฉันจะเห็นการใช้งานที่คุณอาจมีตัวจัดการเหตุการณ์ซึ่งเปลี่ยน JSON เป็น HTML หรือรูปแบบอื่น ๆ ... ในกรณีเช่นนี้มันจะใช้ได้อย่างสมบูรณ์แบบ วิเคราะห์ JSON และสร้างรูปแบบเอกสารอื่น ...

[
  "div":
  {
    "p":"hello",
    "p":"universe"
  }
  "div":
  {
    "h1":"Heading 1",
    "p":"another paragraph"
  }
]

สามารถแยกวิเคราะห์ตัวอย่างเช่น html ได้อย่างง่ายดาย

<body>
 <div>
  <p>hello</p>
  <p>universe</p>
 </div>
 <div>
  <h1>Heading 1</h1>
  <p>another paragraph</p>
 </div>
</body>

ฉันเห็นเหตุผลที่อยู่เบื้องหลังคำถาม แต่มันยืน ... ฉันไม่เชื่อใจ


อาร์เรย์ตัวอย่างแรกของคุณไม่มีเครื่องหมายจุลภาค นอกจากนี้มันไม่สอดคล้องกับตัวเอง หากคุณกำลังจะใช้พจนานุกรมเป็นคอลเลกชันที่สั่งซื้ออาร์เรย์ด้านนอกของคุณก็ควรจะเป็นวัตถุ {"div":{"p":"hello","p":"universe"}, "div":{"h1":"Heading 1","p":"another paragraph"}}กล่าวคือ ตอนนี้ผู้คนจำนวนมากและเฟรมเวิร์กถือว่าวัตถุ JSON เป็นพจนานุกรมที่ไม่มีการเรียงลำดับ แต่ JavaScript และเช่น API ของ MongoDB นั้นใช้การเรียงลำดับของคีย์ภายในพจนานุกรมดังนั้นสิ่งที่คุณแนะนำ (พจนานุกรมที่สั่งซื้อ) จะไม่แปลก คุณแค่ต้องการเครื่องมือแยกวิเคราะห์พิเศษ
binki

2

การขอจุดประสงค์มีคำตอบต่าง ๆ :

การใช้ JSON เพื่อทำให้เป็นอันดับวัตถุ (JavaScriptObjectNotation) แต่ละองค์ประกอบพจนานุกรมจะจับคู่กับคุณสมบัติของวัตถุที่แยกต่างหากดังนั้นรายการต่าง ๆ ที่กำหนดค่าสำหรับคุณสมบัติเดียวกันไม่มีความหมาย

อย่างไรก็ตามฉันพบคำถามเดียวกันจากกรณีการใช้งานที่เฉพาะเจาะจงมาก: การเขียนตัวอย่าง JSON สำหรับการทดสอบ API ฉันสงสัยว่าจะเพิ่มความคิดเห็นลงในไฟล์ JSON ของเราได้อย่างไรโดยไม่ทำลายการใช้งาน ข้อมูลจำเพาะของ JSON ไม่ทราบความคิดเห็นดังนั้นฉันจึงคิดวิธีที่ง่ายมาก:

เมื่อต้องการใช้คีย์ที่ซ้ำกันจะแสดงความคิดเห็นตัวอย่าง JSON ของเรา ตัวอย่าง:

{ "property1" : "value1", "REMARK" : "... prop1 controls ...", "property2" : "value2", "REMARK" : "... value2 raises an exception ...", }

JSON serializers ที่เราใช้อยู่นั้นไม่มีปัญหากับการซ้ำซ้อน "REMARK" เหล่านี้และรหัสแอปพลิเคชันของเราจะไม่สนใจค่าใช้จ่ายเล็กน้อยนี้

ดังนั้นแม้ว่าจะไม่มีความหมายในเลเยอร์ของแอปพลิเคชัน แต่ข้อมูลที่ซ้ำกันเหล่านี้ให้วิธีการที่มีคุณค่าในการเพิ่มความคิดเห็นในตัวอย่างการทดสอบของเราโดยไม่ทำลายการใช้งานของ JSON


นี่เป็นความคิดที่ไม่ดี โดยการรวมคีย์ที่ซ้ำกันแม้ว่าคุณไม่จำเป็นต้องอ่านข้อมูลในนั้นก็ตามคุณก็ต้องพึ่งพาพฤติกรรมที่ไม่ได้กำหนด ตัวแยกวิเคราะห์บางตัวเช่นตัวแยกวิเคราะห์ JSON-java ของ Crockford มีข้อยกเว้นและปฏิเสธที่จะแยกวิเคราะห์ข้อมูล
Richard Smith

จริงการทำงานอย่างสมบูรณ์แบบในสภาพแวดล้อมของเราเพื่อตอบสนองความต้องการของฉันแม้ว่าผมเห็นด้วยกับคุณว่ามันเป็นชนิดออกจากสเปคบาง;)
aknoepfel

@RichardSmith ฉันจะบอกว่า parsers และรายละเอียด ES ที่ใหม่กว่านั้นได้กำหนดพฤติกรรมไว้
binki

2

การโพสต์และตอบคำถามเนื่องจากมีความคิดและความสับสนที่ล้าสมัยมากมายเกี่ยวกับมาตรฐาน ณ เดือนธันวาคม 2560 มีสองมาตรฐานการแข่งขัน:

RFC 8259 - https://tools.ietf.org/html/rfc8259

ECMA-404 - http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf

json.org แสดงให้เห็น ECMA-404 เป็นมาตรฐาน แต่เว็บไซต์นี้ไม่ได้ปรากฏเป็นผู้มีอำนาจ ในขณะที่ฉันคิดว่ามันยุติธรรมที่จะพิจารณาสิทธิ์ของ ECMA สิ่งที่สำคัญคือที่นี่ความแตกต่างเพียงอย่างเดียวระหว่างมาตรฐาน (เกี่ยวกับคีย์เฉพาะ) คือ RFC 8259 กล่าวว่าคีย์ควรไม่ซ้ำกันและ ECMA-404 กล่าวว่าพวกเขาไม่จำเป็นต้องเป็น เป็นเอกลักษณ์

RFC-8259:

"ชื่อภายในวัตถุควรเป็นชื่อเฉพาะ"

คำว่า "ควร" ในตัวพิมพ์ใหญ่ทั้งหมดนั้นมีความหมายภายในโลก RFC ที่กำหนดไว้ในมาตรฐานอื่น (BCP 14, RFC 2119 - https://tools.ietf.org/html/rfc2119 ) เป็นมาตรฐานอื่น

  1. ควรคำนี้หรือคำคุณศัพท์ "แนะนำ" หมายความว่าอาจมีเหตุผลที่ถูกต้องในสถานการณ์พิเศษที่จะไม่สนใจรายการใดรายการหนึ่ง แต่จะต้องเข้าใจและชั่งน้ำหนักอย่างรอบคอบก่อนเลือกหลักสูตรอื่น

ECMA-404:

"ไวยากรณ์ JSON ไม่ได้กำหนดข้อ จำกัด ใด ๆ ของสตริงที่ใช้เป็นชื่อไม่ต้องการให้สตริงชื่อนั้นไม่ซ้ำกันและไม่ได้กำหนดนัยสำคัญใด ๆ ให้กับการเรียงลำดับของคู่ชื่อ / ค่า"

ดังนั้นไม่ว่าคุณจะเชือดมันไม่มีมันเป็น JSON

เหตุผลที่กำหนดสำหรับคำแนะนำคีย์เฉพาะใน RFC 8259 คือ

วัตถุที่มีชื่อไม่ซ้ำกันสามารถใช้งานร่วมกันได้ในแง่ที่ว่าการใช้งานซอฟต์แวร์ทั้งหมดที่ได้รับวัตถุนั้นจะตกลงในการแมปชื่อ - ค่า เมื่อชื่อภายในวัตถุไม่ซ้ำกันพฤติกรรมของซอฟต์แวร์ที่ได้รับวัตถุดังกล่าวจะไม่สามารถคาดเดาได้ การใช้งานจำนวนมากรายงานคู่สุดท้ายของชื่อ / ค่าเท่านั้น การใช้งานอื่น ๆ รายงานข้อผิดพลาดหรือล้มเหลวในการแยกวิเคราะห์วัตถุและการใช้งานบางอย่างรายงานชื่อคู่ / ค่าทั้งหมดรวมถึงรายการที่ซ้ำกัน

กล่าวอีกนัยหนึ่งจากมุมมอง RFC 8259 ใช้ได้ แต่ตัวแยกวิเคราะห์ของคุณอาจมีปัญหาและไม่มีคำสัญญาว่าจะมีการจับคู่กับคีย์นั้นหรือไม่ถ้ามี จากมุมมองของ ECMA-404 (ซึ่งฉันได้รับมอบหมายเป็นการส่วนตัว) เป็นสิ่งที่ถูกต้องเป็นระยะเวลา สำหรับฉันนี่หมายความว่าโปรแกรมแยกวิเคราะห์ใด ๆ ที่ปฏิเสธที่จะแยกวิเคราะห์จะเสีย อย่างน้อยควรแยกวิเคราะห์ตามมาตรฐานทั้งสองนี้ แต่วิธีที่ทำให้มันกลายเป็นวัตถุพื้นเมืองที่คุณเลือกได้ไม่ว่าจะในกรณีใด ๆ คีย์ที่ไม่ซ้ำกันหรือไม่ขึ้นอยู่กับสภาพแวดล้อมและสถานการณ์อย่างสมบูรณ์และไม่มีสิ่งใดในมาตรฐานที่เริ่มต้นด้วย


json.org จริงมาก่อนมาตรฐาน ECMA ฉันเชื่อว่ามันเป็นจริงโดย Crockford ตัวเอง (ซึ่งเป็นเหตุผลที่มันมีปลั๊กไร้ยางอายสำหรับหนังสือของเขา) ณ จุดนั้นมันเป็นสิทธิของ JSON
สูงสุด

1

มันไม่ได้กำหนดไว้ในมาตรฐาน ECMA JSON และโดยทั่วไปแล้วการขาดความหมายในมาตรฐานหมายถึง "อย่าพึ่งพางานนี้ในทุก ๆ ที่"

หากคุณเป็นนักการพนันเอ็นจิ้น JSON "จำนวนมาก" จะอนุญาตการทำซ้ำและเพียงแค่ใช้ค่าสุดท้ายที่ระบุ นี้:

var o = {"a": 1, "b": 2, "a": 3}

กลายเป็นสิ่งนี้:

Object {a: 3, b: 2}

แต่ถ้าคุณไม่ใช่นักการพนันอย่าวางใจในมัน!


1

มาตรฐานจะบอกสิ่งนี้:

ภาษาการเขียนโปรแกรมนั้นขึ้นอยู่กับว่าพวกเขาสนับสนุนวัตถุหรือไม่และถ้าเป็นเช่นนั้นลักษณะและข้อ จำกัด ของวัตถุที่เสนอ แบบจำลองของระบบวัตถุสามารถแตกต่างกันอย่างดุเดือดและกำลังพัฒนาอย่างต่อเนื่อง JSON ให้สัญกรณ์อย่างง่ายสำหรับการแสดงคอลเลกชันของคู่ชื่อ / ค่า ภาษาการเขียนโปรแกรมส่วนใหญ่จะมีคุณสมบัติบางอย่างในการเป็นตัวแทนของคอลเลกชันดังกล่าวซึ่งสามารถไปตามชื่อเช่นบันทึก, struct, dict, map, hash หรือวัตถุ

ข้อผิดพลาดอยู่ใน node.js อย่างน้อย รหัสนี้สำเร็จใน node.js

try {
     var json = {"name":"n","name":"v"};
     console.log(json); // outputs { name: 'v' }
} catch (e) {
     console.log(e);
}

1
ไม่ใช่ข้อผิดพลาดและส่วนที่คุณยกมาอธิบายว่าทำไมมันไม่ใช่: ภาษาต่าง ๆ ทำงานแตกต่างกันและตัวแยกวิเคราะห์ JSON จะทำสิ่งที่เป็นธรรมชาติที่สุดสำหรับภาษานั้น ไม่ว่าในกรณีใดคำตอบนี้จะไม่เพิ่มสิ่งใด ๆ ที่ผู้ใช้ 454322 ยังไม่ได้กล่าวข้างต้น
Richard Smith

1

ตาม RFC-7159 มาตรฐานปัจจุบันของ JSON ที่เผยแพร่โดย Internet Engineering Task Force (IETF) ระบุว่า "ชื่อภายในวัตถุควรเป็นเอกลักษณ์" อย่างไรก็ตามตาม RFC-2119 ซึ่งกำหนดคำศัพท์ที่ใช้ในเอกสาร IETF คำว่า "ควร" ในความเป็นจริงหมายถึง "... อาจมีเหตุผลที่ถูกต้องในสถานการณ์พิเศษที่จะไม่สนใจรายการใดรายการหนึ่ง แต่ต้องเข้าใจและ ชั่งน้ำหนักอย่างรอบคอบก่อนเลือกหลักสูตรอื่น " สิ่งนี้มีความหมายว่าในขณะที่มีการแนะนำปุ่มที่ไม่ซ้ำใครก็ไม่จำเป็นต้อง เราสามารถมีคีย์ที่ซ้ำกันในวัตถุ JSON และมันจะยังคงถูกต้อง

จากการใช้งานจริงฉันเห็นค่าจากคีย์สุดท้ายถูกพิจารณาเมื่อพบคีย์ที่ซ้ำกันใน JSON


0

ใน C # หากคุณ deserialise ถึง a Dictionary<string, string>จะใช้คู่ของค่าคีย์สุดท้าย:

string json = @"{""a"": ""x"", ""a"": ""y""}";
var d = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
// { "a" : "y" }

ถ้าคุณพยายามจะเลิก

class Foo
{
    [JsonProperty("a")]
    public string Bar { get; set; }

    [JsonProperty("a")]
    public string Baz { get; set; }
}

var f = JsonConvert.DeserializeObject<Foo>(json);

คุณได้รับNewtonsoft.Json.JsonSerializationExceptionข้อยกเว้น


2
ฉันเดาว่าเป็นสิ่งที่การใช้งานมากที่สุด (ถ้าไม่ทั้งหมด) ทำ แต่ไม่ตอบคำถามของฉันถ้ามันถูกต้องตามข้อกำหนดของ JSON
หนีบ

@svidgen: นี่ไม่ใช่แม้แต่การใช้งานของ Microsoft ... เป็นห้องสมุดบุคคลที่สาม
BoltClock

@BoltClock Ah, touche
svidgen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.