JSON रूपांतरण के दौरान JSON कुंजियों के क्रम को CSV में रखें


82

मैं यहाँ उपलब्ध JSON लाइब्रेरी का उपयोग कर रहा हूँ, http://www.json.org/java/index.html एक CS स्ट्रिंग जो मुझे CSV में बदलना है। लेकिन मेरे पास जो समस्या है, रूपांतरण के बाद चाबियों का क्रम खो गया है।

यह रूपांतरण कोड है:

    JSONObject jo = new JSONObject(someString);
    JSONArray ja = jo.getJSONArray("items");
    String s = CDL.toString(ja);
    System.out.println(s);

यह "someString" की सामग्री है:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ]
}

यह परिणाम है:

WO,QU,WR,QA,NO
hasd,asd,qwe,end,qwer

जबकि मुझे उम्मीद है कि चाबियों के क्रम को बनाए रखना है:

WR,QU,QA,WO,NO
qwe,asd,end,hasd,qwer

क्या इस पुस्तकालय का उपयोग करने का कोई परिणाम हो सकता है? यदि नहीं, तो क्या कोई अन्य पुस्तकालय है जो परिणाम में चाबियों के क्रम को रखने की क्षमता प्रदान करेगा?


4
शब्दकोश अनसोल्ड हैं। मुझे नहीं लगता कि JSON ऑर्डर की गारंटी देता है।
फल्मरी डे

2
जानकारी के लिए धन्यवाद। लेकिन मेरे पास अपने आवेदन में JSON का उपयोग करने के अलावा और कोई विकल्प नहीं है और मेरे आवेदन को कुंजियों के क्रम को बनाए रखने की आवश्यकता है :(
Hery

मेरे मामले में यह मुद्दा एक आदेश की कमी नहीं है, लेकिन यह गैर-नियतात्मक है। कभी-कभी मुझे चाबी fooसे पहले चाबी मिलती है barऔर कभी-कभी barपहले foo। इससे परीक्षण लिखना मुश्किल हो जाता है।
श्रीधर सरनोबत

मुझे भी इस आवश्यकता का सामना करना पड़ा है, लेकिन यह वास्तविक समय परीक्षण के दौरान तेजी से लॉग तुलना के लिए है। मुझे एक उच्च थ्रू-पुट एप्लिकेशन के लिए वास्तविक समय में पहले से उत्पन्न लॉग से नए उत्पन्न लॉग की तुलना करने की आवश्यकता है। इसे करने के अन्य तरीके भी हैं, लेकिन मुझे लगता है कि लॉग JSON प्रारूप में होंगे। हालाँकि, CPU उपयोग को कम करने के लिए, मैं अपना स्वयं का डायरेक्ट-टू-स्ट्रिंग JSON लेखक लिख रहा हूँ। मुझे आंतरिक संरचना की बिल्कुल भी आवश्यकता नहीं है, और मैं लॉग के तेजी से स्ट्रिंग तुलना के लिए महत्वपूर्ण आदेश बनाए रख सकता हूं। पूर्वानुमान योग्य आदेश प्राप्त करने के लिए अच्छे कारण हैं।
जो लप्प

JSON को एक विशिष्ट आदेशित CSV फ़ाइल में बदलने के लिए अपना स्वयं का कोड लिखें, इस तरह से आप दोनों स्वरूपों का सम्मान करते हैं।
Martijn Scheffer

जवाबों:


95

इसे करने के तरीके (हैक) हैं ... लेकिन आपको ऐसा नहीं करना चाहिए।

JSON में, एक ऑब्जेक्ट इस प्रकार परिभाषित किया गया है:

ऑब्जेक्ट नाम / मान जोड़े का एक अनियंत्रित सेट है।

Http://json.org देखें ।

JSON के अधिकांश कार्यान्वयन किसी ऑब्जेक्ट के नाम / मूल्य जोड़े के आदेश को संरक्षित करने का कोई प्रयास नहीं करते हैं, क्योंकि यह (परिभाषा के अनुसार) महत्वपूर्ण नहीं है।

यदि आप चाहते हैं कि ऑर्डर संरक्षित हो, तो आपको अपनी डेटा संरचना को फिर से परिभाषित करने की आवश्यकता है; जैसे

{
    "items":
    [
        [
            {"WR":"qwe"},
            {"QU":"asd"},
            {"QA":"end"},
            {"WO":"hasd"},
            {"NO":"qwer"}
        ],
    ]
}

या अधिक बस:

{
    "items":
    [
        {"WR":"qwe"},
        {"QU":"asd"},
        {"QA":"end"},
        {"WO":"hasd"},
        {"NO":"qwer"}
    ]
}

जाँच करना

जानकारी के लिए धन्यवाद, लेकिन मेरे पास JSON का उपयोग करने के अलावा और कोई विकल्प नहीं है और मेरे आवेदन में JSON ऑब्जेक्ट की परिभाषा की परवाह किए बिना कुंजी के क्रम को बनाए रखने की आवश्यकता है ... मुझे JSON फ़ाइल का प्रारूप बदलने की अनुमति नहीं है भी...

आपको उस फ़ाइल संरचना को डिज़ाइन करने वाले के साथ एक कठिन वार्तालाप करने की आवश्यकता है और आपको इसे बदलने नहीं देगा। यह है / वे सादे गलत हैं। आपको उन्हें मनाने की जरूरत है।

यदि वे वास्तव में आपको इसे बदलने नहीं देंगे:

  • आपको इसे JSON नहीं कहने पर जोर देना चाहिए ... 'क्योंकि यह नहीं है।
  • आपको यह इंगित करना चाहिए कि आपको इस "नहीं JSON" प्रारूप को संभालने के लिए विशेष रूप से कोड लिखना / संशोधित करना होगा ... जब तक कि आप कुछ JSON कार्यान्वयन नहीं पा सकते हैं जो आदेश को संरक्षित करता है। यदि वे एक भुगतान करने वाले ग्राहक हैं, तो सुनिश्चित करें कि वे इस अतिरिक्त काम के लिए भुगतान करते हैं जो आपको करना है।
  • आपको यह इंगित करना चाहिए कि यदि "JSON नहीं" को किसी अन्य उपकरण द्वारा उपयोग करने की आवश्यकता है, तो यह समस्याग्रस्त होने वाला है। दरअसल, यह समस्या बार-बार आएगी ...

इस तरह की बात वास्तव में बुरी है। एक ओर, आपका सॉफ़्टवेयर एक अच्छी तरह से स्थापित / लंबे समय तक चलने वाले विनिर्देश का उल्लंघन कर रहा होगा, जिसे इंटरऑपरेबिलिटी को बढ़ावा देने के लिए डिज़ाइन किया गया है। दूसरी ओर, नाइट-विट्स जिन्होंने इस लंगड़े को डिज़ाइन किया है (JSON नहीं!) फ़ाइल प्रारूप संभवतः अन्य लोगों के सिस्टम आदि को बंद कर रहे हैं 'क्योंकि सिस्टम उनकी बकवास का सामना नहीं कर सकता है ।

अपडेट करें

यह भी पढ़ने योग्य है कि JSON RFC (RFC 7159) इस विषय पर क्या कहता है। यहाँ कुछ अंश दिए गए हैं:

RFC 4627 के प्रकाशन के बाद के वर्षों में, JSON ने बहुत व्यापक उपयोग पाया है। इस अनुभव से कुछ प्रतिमानों का पता चला है, जो इसकी विशिष्टताओं द्वारा अनुमति देते समय, अंतर-समस्या का कारण बने हैं।

जावास्क्रिप्ट ऑब्जेक्ट नोटेशन (JSON) संरचित डेटा के क्रमांकन के लिए एक पाठ प्रारूप है। ...

JSON चार आदिम प्रकारों (तारों, संख्याओं, बूलियन और नल) और दो संरचित प्रकारों (वस्तुओं और गिरफ्तारियों) का प्रतिनिधित्व कर सकता है।

एक वस्तु शून्य या अधिक नाम / मूल्य जोड़े का एक अनियोजित संग्रह है, जहां एक नाम एक स्ट्रिंग है और एक मूल्य एक स्ट्रिंग, संख्या, बूलियन, अशक्त, वस्तु या सरणी है।

JSON पार्सिंग पुस्तकालयों में यह देखा गया है कि वे कॉलिंग सॉफ्टवेयर में दिखाई देने वाली वस्तु सदस्यों के क्रम को बनाते हैं या नहीं। कार्यान्वयन जिनका व्यवहार सदस्य के आदेश पर निर्भर नहीं करता है, इस अर्थ में अंतर होगा कि वे इन अंतरों से प्रभावित नहीं होंगे।


3
@YogeshSomani - "समाधान" एक उचित JSON लाइब्रेरी को पकड़ना है, और इसे "हैक" करना है ताकि यह प्रमुख ऑर्डर को संरक्षित रखे। उदाहरण के लिए गैरी का जवाब देखें। लेकिन आपको ऐसा करने के लिए एक मानक JSON लाइब्रेरी की अपेक्षा नहीं करनी चाहिए क्योंकि यह JSON विनिर्देशन के दुरुपयोग को प्रोत्साहित करने के लिए एक BAD IDEA है। असली समाधान JSON का सही उपयोग करने के लिए आपके एप्लिकेशन को ठीक करना है।
स्टीफन C

10
शुद्धतम और निरपेक्ष होने के लिए बहुत अच्छा है, लेकिन चलो खुद को बच्चा नहीं बनाते हैं, वास्तविक दुनिया के परिदृश्य हैं जहां एक JSON फ़ाइल को अपने परिभाषित उपकरणों के क्रम को संरक्षित करने की आवश्यकता होती है। किसी भी क्रम में उन्हें पारित करने और स्वीकार करने के लिए एक मौलिक जौनसारी दृष्टिकोण है, लेकिन मुझे लगता है कि एक डॉक्यूमेंट को लेने में सक्षम होने और समानता में / deserialize करने के लिए सक्षम होने की क्षमता से अधिक महत्वपूर्ण है। यह एक सामान्य उपयोग का मामला है, एक json दस्तावेज़ लेने के लिए और इसका उपयोग किसी अन्य मानक WDDX, HTML, आदि के दस्तावेज़ को बनाने के लिए किया जाता है, जहाँ आदेश देने की आवश्यकता होती है
एंड्रयू नॉर्मन

3
@AndrewNorman - अगर आपने जो "ज़रूरत" के बारे में कहा था वह वास्तव में सच था, तो विनिर्देश होना चाहिए और इसे बदल दिया जाना चाहिए था। वास्तविकता यह है कि JSON में अन्य तरीकों से ऑर्डरिंग का प्रतिनिधित्व करना आसान है।
स्टीफन सी।

2
JSON को केवल यह जानकारी चाहिए कि कुंजियों के क्रम में जानकारी को इनकोड नहीं किया जाना चाहिए; यह JSON अन्यथा नहीं है। क्रमबद्धता की संगति एक अलग मुद्दा है। एक एकल ऐप के भीतर, एक सामान्य JSON लाइब्रेरी का उपयोग करके आमतौर पर स्थिरता की गारंटी दी जा सकती है, लेकिन अपवाद भी हैं, जैसे कि एक एकल समाधान कई प्लेटफार्मों या चौखटे तक फैला हुआ है। इन मामलों में, आपको या तो असंगति (अक्षमता का परिचय) से निपटने के लिए एक रास्ता खोजना होगा, या आप स्थिरता सुनिश्चित करने का एक तरीका खोजेंगे। दोनों दृष्टिकोण मान्य हैं।
जो लैप

2
"JSON को केवल यह जानकारी चाहिए कि जानकारी कुंजियों के क्रम में एन्कोडेड न हो; यह JSON अन्यथा नहीं है।" । मुझे लगता है कि आपने गलत लिखा है। सही कथन यह है कि "JSON को इस बात की आवश्यकता नहीं है कि जानकारी कुंजियों के क्रम में एन्कोडेड है"। इन दोनों कथनों में बड़ा अंतर है ....
स्टीफन C

47

आदेश को बनाए रखना काफी सरल है। मुझे DB लेयर से UI लेयर तक ऑर्डर बनाए रखने में समान समस्या थी।

JSONObject.java फ़ाइल खोलें। यह आंतरिक रूप से HashMap का उपयोग करता है जो आदेश को बनाए नहीं रखता है।

इसे LinkedHashMap में बदलें:

    //this.map = new HashMap();
    this.map = new LinkedHashMap();

इसने मेरे लिए काम किया। टिप्पणियों में क्या है मुझे जानने दें। मेरा सुझाव है कि JSON लाइब्रेरी में एक और JSONObject क्लास होनी चाहिए जो JSONOrderdObject.java की तरह ऑर्डर बनाए रखे। मैं नाम चुनने में बहुत गरीब हूं।


2
svn चेकआउट जसन-सरल। फ़ाइल को संशोधित करें। org.json.simple.JSONObject, <code> JOSNObject, LinkedHashMap का विस्तार करता है ... </ code> <code> .. HashMap .. </ code> से, आयात ठीक करें और यह मेरे लिए काम करता है। v1.1.1।
मार्कू

2
यह एक महान एक-लाइन समाधान है जिसे मैंने कभी कोशिश करने के लिए नहीं सोचा होगा। पूरी तरह से काम करता है, और मुझे अपना कोई अन्य कोड नहीं बदलना पड़ा। +1
DaaaahWhoosh

महान तय। आप एक नायक हैं सर
ग्रेगरी Nowakowski

मैंने काम नहीं किया, मैंने आयात को जोड़ा, जैसे आपने कहा, उसे बदल दिया, यहां तक ​​कि इस तरह से करने की कोशिश की: this.map = new LinkedHashMap<String, Object>();अभी भी काम नहीं करता। कृपया सहायता कीजिए ?
तारेक

4
हा हा वास्तव में? अपनी आवश्यकताओं को पूरा करने के लिए JSON लाइब्रेरी को संशोधित करना? मैं बस कंपनी के ज्ञान के आधार में नीचे जाने की कल्पना कर सकता हूं। "अपने मावन को साफ स्थापित करें, जार डाउनलोड करें, इसे ढूंढें, इसे अपघटित करें, फिर HashMap को LinkedHubMap के साथ बदलें"। यह मल्टी डेवलपर टीमों (नहीं) के लिए बहुत अच्छा काम करेगा।
क्रिस नेवे

23

JSONObject.javaजो भी नक्शा पास करवा लो। यह हो सकता है LinkedHashMapया TreeMapयह hashmapकेवल तभी लेगा जब नक्शा अशक्त होगा।

यहां JSONObject.javaक्लास का कंस्ट्रक्टर है जो मैप की चेकिंग करेगा।

 public JSONObject(Map paramMap)
  {
    this.map = (paramMap == null ? new HashMap() : paramMap);
  }

इसलिए एक जसन ऑब्जेक्ट कंस्ट्रक्शन बनाने से पहले LinkedHashMapऔर फिर उसे कंस्ट्रक्टर को इस तरह से पास करें,

LinkedHashMap<String, String> jsonOrderedMap = new LinkedHashMap<String, String>();

jsonOrderedMap.put("1","red");
jsonOrderedMap.put("2","blue");
jsonOrderedMap.put("3","green");

JSONObject orderedJson = new JSONObject(jsonOrderedMap);

JSONArray jsonArray = new JSONArray(Arrays.asList(orderedJson));

System.out.println("Ordered JSON Fianl CSV :: "+CDL.toString(jsonArray));

इसलिए JSONObject.javaकक्षा को बदलने की कोई आवश्यकता नहीं है । आशा है कि यह किसी की मदद करता है।


3
अच्छा जवाब, सामान्य जावा के लिए काम करता है, लेकिन Android पर काम नहीं करता है। मैं एंड्रॉइड में org.json.JSONObject की जांच करता हूं, यह एक दया है कि एंड्रॉइड अभी भी आंतरिक रूप से बनाए गए हैशमैप का उपयोग करता है। यह केवल पैरामांप से हैशपॉप में नाम / मूल्य जोड़े की नकल करता है ... :(
白 name

मैंने JsonObject का आदेश दिया, लेकिन जब मैंने उस ऑब्जेक्ट को एक JsonArray में जोड़ने का प्रयास किया तो यह मुझे अनियंत्रित कर देता है। मुझे सरणी में ऑब्जेक्ट डालने की आवश्यकता है, मुझे सरणी की वस्तुओं की आवश्यकता है फिर मैंने सरणी में हेडर डाल दिया और वापस भेज दिया। पूर्व: एक वस्तु; {CUSTOMER_SECTOR_ID = 611, CUSTOMER_NO = 0000003204, CUSTOMER_NAME = MARMAR_NAMES - KARAS GIDA KARAS TÜKETİM MADDELYİ GIDA LOJ।} मुझे यह प्राप्त होता है, यदि मुझे सरणी में दो वस्तुएँ डालनी पड़ती हैं: [{CUSTOMER_NAME}: 0000003122 "," CUSTOMER_SECTOR_ID ":" 611 "}, {" CUSTOMER_NAME ":" M ":" 0013114714 "," CUSTOMER_SECTOR_ID: ":" 611 "}] जैसा कि आप देखते हैं कि यह गलत है। मैं इसे कैसे ठीक कर सकता हूं
साहिन यान्लिक

2
@ दीपक नागराज मैंने आपके समाधान की कोशिश की है, लेकिन यह काम नहीं किया, JSONObjectमेरे रूप में आदेश नहीं दिया है LinkedHashMap। क्या आप हमारे साथ हैं?org.json ?
इस्माइल सेन

1
यह एक नहीं है org.json.. यह एक HashMapआंतरिक रूप से परिभाषित करता है , जो भी Mapआप इसे देते हैं: @Deepak क्या आप हमें उस कार्यान्वयन के लिए इंगित कर सकते हैं जिसका उपयोग किया गया है?
कैम्पा

8
यह org.jsonलाइब्रेरी के साथ काम नहीं करेगा । जब आप एक नए JSONObjectऑब्जेक्ट का निर्माण करते हैं , तो एक नक्शे को एक तर्क के रूप में पारित करते हुए, इसे हमेशा ए में परिवर्तित किया जाएगा HashMap। कंस्ट्रक्टर सबसे पहले एक नया नक्शा बनाता है: this.map = new HashMap<String, Object>();और फिर आपके नक्शे पर लूप करता है, उसके हर तत्व की नकल करता है HashMap
इटाची

13

इस तरह की समस्या के लिए एक अधिक क्रिया, लेकिन मोटे तौर पर लागू समाधान डेटा संरचनाओं की एक जोड़ी का उपयोग करना है: आदेश को समाहित करने के लिए एक सूची, और संबंधों को शामिल करने के लिए एक नक्शा।

उदाहरण के लिए:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ],
    "itemOrder":
        ["WR", "QU", "QA", "WO", "NO"]
}

आप आइटमऑडर सूची को पुनरावृत्त करते हैं, और मानचित्र मानों को देखने के लिए उन का उपयोग करते हैं। ऑर्डरिंग संरक्षित है, जिसमें कोई कीचड़ नहीं है।

मैंने इस विधि का कई बार उपयोग किया है।


यह जटिल हो जाता है अगर आपका नक्शा केवल साधारण कुंजी-मूल्य वाले जोड़े नहीं है ...
zfj3ub94rf576hc4eegm

10

प्रतिबिंबित का उपयोग कर एक और हैकी समाधान:

JSONObject json = new JSONObject();
Field map = json.getClass().getDeclaredField("map");
map.setAccessible(true);//because the field is private final...
map.set(json, new LinkedHashMap<>());
map.setAccessible(false);//return flag

1
मुझे आपका जवाब नहीं मिला
एम। उस्मान खान

1
ट्रिक क्लास को डिफॉल्ट रूप से HashMap के बजाय LinkedHashMap का उपयोग करने के लिए आंतरिक रूप से संशोधित करने के लिए है, जिससे JSON ऑब्जेक्ट आपके द्वारा लगाए गए क्रम में डेटा होता है, यह सीधे सॉर्ट नहीं किया जाता है, लेकिन यह मेरे लिए काम करता है क्योंकि डेटा पहले से ही सॉर्ट किया गया है ।
fabe

अच्छा लग रहा है, लेकिन JSON String AFTER map.set (json, new LinkedHashMap <> ()) को पार्स कैसे करें; क्योंकि कंस्ट्रक्शन सही में Json String पास है? जैसे, नया JSONObject (jsonString)।
एम। उस्मान खान

इसके अलावा, यह काम नहीं किया। फ़ील्ड "मैप" नहीं है, एक फ़ील्ड "nameValuePairs" है जो पहले से ही LinckedHashMap है, और यह अभी भी काम नहीं करता है।
एम। उस्मान खान

1
JSONObject का आप किस कार्यान्वयन का उपयोग कर रहे हैं? मैं org.json संस्करण 20140107 का उपयोग कर रहा हूं और इसे मेरे लिए काम करने के तरीके और ऑर्डर को संरक्षित करना था।
fabe


4

बस एक ही समस्या पर ठोकर खाई, मुझे विश्वास है कि लेखक द्वारा उपयोग किया जाने वाला अंतिम समाधान एक कस्टम कंटेनर का उपयोग करने में शामिल है:

public static Values parseJSONToMap(String msgData) {
    JSONParser parser = new JSONParser();
    ContainerFactory containerFactory = new ContainerFactory(){
        @Override
        public Map createObjectContainer() {
            return new LinkedHashMap();
        }

        @Override
        public List creatArrayContainer() {
            return null;
        }
    };
    try {
        return (Map<String,Object>)parser.parse(msgData, containerFactory);
    } catch (ParseException e) {
        log.warn("Exception parsing JSON string {}", msgData, e);
    }
    return null;
}  

http://juliusdavies.ca/json-simple-1.1.1-javadocs/org/json/simple/parser/JSONParser.html#parse(java.io.eader.org.jim.simple.parser.ContainerFactory) देखें


वास्तव में बहुत अच्छा और व्यावहारिक समाधान। कंटेनरफैक्टरी के लिए स्थानीय अनाम आंतरिक वर्ग लिखने की विधि के बारे में कैसे?
शैलेश सक्सेना

3

हल किया।

मैंने यहां से JSON.simple लाइब्रेरी का उपयोग किया। https://code.google.com/p/json-simple/ ने चाबियाँ के क्रम को बनाए रखने के लिए JSON स्ट्रिंग को पढ़ने के लिए और यहाँ से JavaCSV लाइब्रेरी का उपयोग करने के लिए http://sourceforge.net/ परियोजनाओं / javacsv / सीएसवी प्रारूप में परिवर्तित करने के लिए।


मुझे आश्चर्य है कि यह काम किया। JSONObject वर्ग ( code.google.com/p/json-simple/source/browse/trunk/src/main/java/… ) के कोड और टिप्पणियों दोनों के मेरे पढ़ने के अनुसार , यह संरक्षित करने के लिए कुछ भी नहीं करता है कुंजियों का क्रम।
स्टीफन C

1
मैंने यहां पूर्ण समाधान निर्दिष्ट नहीं किया है, लेकिन इसका सार यह है कि json-simple एक कारखाना प्रदान करता है जिसके साथ आप json ऑब्जेक्ट्स को संग्रहीत करने के लिए उपयोग किए जाने वाले डेटा संरचना को निर्दिष्ट कर सकते हैं। बस LinkedHashMap का उपयोग करने के लिए निर्दिष्ट करें।
हारी

@ Hery, मैं एक ही मुद्दे का सामना कर रहा हूँ, लेकिन मैं इसे हल नहीं कर सका। मैं a बनाने के org.jsonलिए कन्वर्ट List<LinkedHahMap>करने JSONArrayके लिए उपयोग करता हूँ CSV, CSVबनाया जाता है, लेकिन मेरे जैसे ही क्रम में नहीं List । मैंने आपके द्वारा यहां प्रस्तुत दो परिवादों का उपयोग करने की कोशिश की है, लेकिन मुझे परिवर्तित करने के तरीके नहीं मिल पाए हैं CSV। क्या आप अधिक जानकारी दे सकते हैं।
इस्माइल सेन

2

मुझे पता है कि यह हल हो गया है और यह सवाल बहुत समय पहले पूछा गया था, लेकिन जैसा कि मैं एक समान समस्या से निपट रहा हूं, मैं इस पर पूरी तरह से अलग दृष्टिकोण देना चाहूंगा:

सरणियों के लिए यह कहता है "एक सरणी मूल्यों का एक संग्रहित संग्रह है।" पर http://www.json.org/ - लेकिन वस्तुओं ( "एक वस्तु नाम / मान युग्म के एक अव्यवस्थित सेट है।") का आदेश दिया नहीं कर रहे हैं।

मुझे आश्चर्य है कि वह वस्तु एक सरणी में क्यों है - इसका तात्पर्य एक आदेश है जो वहां नहीं है।

{
"items":
[
    {
        "WR":"qwe",
        "QU":"asd",
        "QA":"end",
        "WO":"hasd",
        "NO":"qwer"
    },
]
}

तो एक समाधान के लिए एक "वास्तविक" सरणी में चाबियाँ डाल दिया जाएगा और इस तरह से प्रत्येक कुंजी के लिए वस्तुओं के रूप में डेटा जोड़ना होगा:

{
"items":
[
    {"WR": {"data": "qwe"}},
    {"QU": {"data": "asd"}},
    {"QA": {"data": "end"}},
    {"WO": {"data": "hasd"}},
    {"NO": {"data": "qwer"}}
]
}

तो यह एक दृष्टिकोण है जो मूल मॉडलिंग और उसके इरादे पर पुनर्विचार करने की कोशिश करता है। लेकिन मैंने परीक्षण नहीं किया है (और मुझे आश्चर्य है) यदि सभी शामिल उपकरण उस मूल JSON सरणी के आदेश को संरक्षित करेंगे।


1
यह मुझे कुंजी पर एक खोज करने की अनुमति नहीं देता है।
मिकेमून

फिर आप क्या चाहते हैं - एक हैश या कुछ ऑर्डर किया !? यदि आप दोनों को संयोजित करना चाहते हैं, तो दोनों बनाएं और उन संरचनाओं में से एक को दूसरे को अनुक्रमित करें .... अन्यथा यह एक डिजाइन समस्या, या मिश्रण हितों के अधिक प्रतीत होता है।
cslotty

1
यह हितों के मिश्रण के बारे में नहीं है, यह एक काफी प्रशंसनीय उपयोग का मामला है, जिसे जावा जैसी भाषाओं में लिंक्डहैशपाम जैसे निर्माणों द्वारा नियंत्रित किया जाता है, एक आदेशित नक्शा जो सम्मिलन आदेश को संरक्षित करता है। फिर मुझे क्या चाहिए, मैं चाहता हूं कि दोनों परिभाषित क्रम में कुंजियों पर पुनरावृति करने में सक्षम हों और साथ ही साथ कुंजियों पर एक त्वरित खोज करें। मुझे लगता है कि @Robotic पैंट द्वारा जवाब बहुत अधिक काम करेगा, हालांकि यह थोड़ा हैकिश है।
मिकेमून

यह सच है, mickeymoon, मैं यह कहने वाला था! लेकिन JSON में यह मौजूद नहीं है, क्या यह है? फिर आपको भाषाओं / तंत्रों को शामिल करना होगा, जो आपको ऐसी चीज़ मुहैया कराएगा।
13

1

वास्तविक दुनिया में, एक एप्लिकेशन के पास लगभग हमेशा जावा बीन या डोमेन होगा जो JSON द्वारा क्रमबद्ध / डी-क्रमांकित / किया जाना है। इसका पहले से ही उल्लेख है कि JSON ऑब्जेक्ट विनिर्देश आदेश की गारंटी नहीं देता है और उस व्यवहार में किसी भी हेरफेर की आवश्यकता को उचित नहीं ठहराता है। मेरे आवेदन में मेरे पास वही परिदृश्य था जहाँ मुझे पठनीयता के उद्देश्य के लिए आदेश को संरक्षित करने की आवश्यकता थी। मैंने अपने जावा बीन को JSON में क्रमबद्ध करने के लिए मानक जैक्सन तरीके का उपयोग किया:

Object object = getObject();  //the source java bean that needs conversion
String jsonString = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(object);

तत्वों के एक निर्धारित सेट के साथ जसन बनाने के लिए मैं सिर्फ जावा बीन में रूपांतरण के लिए उपयोग किए जाने वाले JSON संपत्ति एनोटेशन का उपयोग करता हूं। नीचे एक उदाहरण:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"name","phone","city","id"})
public class SampleBean implements Serializable {
    private int id;
    private String name:
    private String city;
    private String phone;

    //...standard getters and setters
}

getObject () ऊपर प्रयोग किया जाता है:

public SampleBean getObject(){
    SampleBean bean  = new SampleBean();
    bean.setId("100");
    bean.setName("SomeName");
    bean.setCity("SomeCity");
    bean.setPhone("1234567890");
    return bean;
}

JSON प्रॉपर्टी ऑर्डर एनोटेशन के अनुसार आउटपुट दिखाता है:

{
    name: "SomeName",
    phone: "1234567890",
    city: "SomeCity",
    id: 100
}

0

सबसे सुरक्षित तरीका संभवतः कुंजी विधि है जो आउटपुट उत्पन्न करने के लिए उपयोग किया जाता है:

new JSONObject(){
  @Override
  public Iterator keys(){
    TreeSet<Object> sortedKeys = new TreeSet<Object>();
    Iterator keys = super.keys();
    while(keys.hasNext()){
      sortedKeys.add(keys.next());
    }
    return sortedKeys.iterator();
  }
};

1
यह बताई गई समस्या का समाधान नहीं करता है। यह कुंजी को हल करने का कारण बनता है ... लेकिन प्रश्न प्रविष्टि के क्रम को संरक्षित करने के लिए कहता है।
स्टीफन सी।

0

पैचफ़ॉर (उत्तर @gary):

$ git diff JSONObject.java                                                         
diff --git a/JSONObject.java b/JSONObject.java
index e28c9cd..e12b7a0 100755
--- a/JSONObject.java
+++ b/JSONObject.java
@@ -32,7 +32,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Collection;
 import java.util.Enumeration;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
@@ -152,7 +152,9 @@ public class JSONObject {
      * Construct an empty JSONObject.
      */
     public JSONObject() {
-        this.map = new HashMap<String, Object>();
+//      this.map = new HashMap<String, Object>();
+        // I want to keep order of the given data:
+        this.map = new LinkedHashMap<String, Object>();
     }

     /**
@@ -243,7 +245,7 @@ public class JSONObject {
      * @throws JSONException
      */
     public JSONObject(Map<String, Object> map) {
-        this.map = new HashMap<String, Object>();
+        this.map = new LinkedHashMap<String, Object>();
         if (map != null) {
             Iterator<Entry<String, Object>> i = map.entrySet().iterator();
             while (i.hasNext()) {

0

आप निम्नलिखित कोड का उपयोग कर सकते हैं कस्टम क्रमबद्ध क्रमांकन और JSON एरे के deserialization (यह उदाहरण मानता है कि आप स्ट्रिंग्स का आदेश दे रहे हैं लेकिन सभी प्रकारों पर लागू किया जा सकता है):

क्रमबद्धता

JSONArray params = new JSONArray();
int paramIndex = 0;

for (String currParam : mParams)
{
    JSONObject paramObject = new JSONObject();
    paramObject.put("index", paramIndex);
    paramObject.put("value", currParam);

    params.put(paramObject);
    ++paramIndex;
}

json.put("orderedArray", params);

अक्रमांकन

JSONArray paramsJsonArray = json.optJSONArray("orderedArray");
if (null != paramsJsonArray)
{
    ArrayList<String> paramsArr = new ArrayList<>();
    for (int i = 0; i < paramsJsonArray.length(); i++)
    {
        JSONObject param = paramsJsonArray.optJSONObject(i);
        if (null != param)
        {
            int paramIndex = param.optInt("index", -1);
            String paramValue = param.optString("value", null);

            if (paramIndex > -1 && null != paramValue)
            {
                paramsArr.add(paramIndex, paramValue);
            }
        }
    }
}

0

आपका उदाहरण:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ]
}

एक तत्व जोड़ें "आइटमऑर्डर"

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ],
    "itemorder":["WR","QU","QA","WO","NO"]
}

यह कोड कॉलम शीर्षक लाइन के बिना वांछित आउटपुट उत्पन्न करता है:

JSONObject output = new JSONObject(json);
JSONArray docs = output.getJSONArray("data");
JSONArray names = output.getJSONArray("itemOrder");
String csv = CDL.toString(names,docs);

इसने CSV के हेडर को हटा दिया, अब मेरे पास पंक्तियाँ हैं लेकिन बिना हेडर के
पेड्रो जोक्विन

0

बजाय jsonObject का उपयोग करने के बजाय CsvSchema का उपयोग करके अपने तरीके को आसान बनाने और सीधे ऑब्जेक्ट को सीएसवी में कनवर्ट करने का प्रयास करें

CsvSchema schema = csvMapper.schemaFor(MyClass.class).withHeader();
        csvMapper.writer(schema).writeValueAsString(myClassList);

और इसमें उस ऑर्डर आईडी का उल्लेख किया गया है जिसमें आपके पूजो में @JsonPropertyOrder है


0

अंडरस्कोर-जावा जावा पढ़ते समय तत्वों के लिए आदेश रखता है। मैं परियोजना का अनुरक्षक हूं।

String json = "{\n"
      + "    \"items\":\n"
      + "    [\n"
      + "        {\n"
      + "            \"WR\":\"qwe\",\n"
      + "            \"QU\":\"asd\",\n"
      + "            \"QA\":\"end\",\n"
      + "            \"WO\":\"hasd\",\n"
      + "            \"NO\":\"qwer\"\n"
      + "        }\n"
      + "    ]\n"
      + "}";
System.out.println(U.fromJson(json));

// {items=[{WR=qwe, QU=asd, QA=end, WO=hasd, NO=qwer}]}

-1

विंक समाधान का परीक्षण किया, और ठीक काम कर रहा है:

@Test
public void testJSONObject() {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    System.out.println(jsonObject.toString());
    assertTrue(jsonObject.toString().startsWith("{\"xxx\":"));
}

@Test
public void testWinkJSONObject() throws JSONException {
    org.apache.wink.json4j.JSONObject jsonObject = new OrderedJSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    assertEquals("{\"bbb\":\"xxx\",\"ccc\":\"xxx\",\"aaa\":\"xxx\",\"xxx\":\"xxx\"}", jsonObject.toString());
}

मावेन निर्भरता: <निर्भरता> <groupId> org.apache.wink </ groupId> <विरूपण साक्ष्य> wink-json4j </ विरूपण साक्ष्य> <संस्करण> 1.4 </ संस्करण> </ निर्भरता>
jgpelaez

@Cypressious के रूप में एक ही उत्तर ... 2 साल पहले पोस्ट किया गया। और उदाहरण कोई वास्तविक मूल्य नहीं जोड़ता है।
स्टीफन सी।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.