2013-06-12 15 views
8

कैसे लिखें, कोई भी क्लास लिखने के लिए मार्गदर्शन कर सकता है जो JSON डेटा लेगा और इसे एक साधारण buffered सूची में पार्स करने का प्रयास करेगा जिससे हम डेटा को वापस पढ़ सकें?मूल JSON पार्सिंग क्लास

पूर्व। JSON

{ name: 'John', age: 56 } 

कुंजी मान जोड़े

name John 
age 56 

की एक तालिका में पार्स किया जा ..will एक पार्स विधि है जो एक तेजी से और सरल बनाने के लिए मदद मिलेगी लिखने के लिए कैसे?

कृपया किसी मौजूदा पुस्तकालय का सुझाव न दें। JSON पार्स करने के लिए एक अवधारणा प्रदान करें।

+2

आप [Gson] (https://code.google.com/p/google-gson/) का उपयोग क्यों नहीं करते? –

+2

यह मान्य JSON नहीं है! – fge

+2

[आपने क्या प्रयास किया है] (http://mattgemmell.com/2008/12/08/what-have-you-tried/) अब तक हमें पूछने के अलावा? –

उत्तर

18

यह जवाब मानता है कि आप वास्तव में एक पार्सर लिखना चाहते हैं और आवश्यक प्रयास करने के लिए तैयार हैं।

आपको JSON के औपचारिक विनिर्देश के साथ प्रारंभ करना होगा। मुझे http://www.ietf.org/rfc/rfc4627.txt मिला है। यह भाषा को ठीक से परिभाषित करता है। आपको spec में सबकुछ लागू करना होगा और इसके लिए परीक्षण लिखना होगा। आपके पार्सर को गलत JSON (जैसे आपकी) के लिए पूरा करना होगा और अपवादों को फेंक देना होगा।

यदि आप एक पार्सर लिखना चाहते हैं, रोकें, सोचें और फिर नहीं करें। यह सही ढंग से काम करने के लिए बहुत काम है। आप जो कुछ भी करते हैं, उसका उचित काम करें - अपूर्ण पार्सर्स एक खतरे हैं और उन्हें कभी वितरित नहीं किया जाना चाहिए।

आपको कोड लिखना चाहिए जो अनुरूप है। यहां spec से कुछ वाक्यांश दिए गए हैं। आप उन्हें समझ में नहीं आता अगर आप ध्यान से अनुसंधान और यह समझने का करना होगा: "। JSON टेक्स्ट यूनिकोड में एन्कोड किया जाएगा डिफ़ॉल्ट एन्कोडिंग UTF-8 है।"

"एक JSON पार्सर को सभी ग्रंथों को स्वीकार करना होगा जो JSON व्याकरण के अनुरूप हैं।"

" एन्कोडिंग विचार: 8 बिट अगर यूटीएफ -8; द्विआधारी यदि UTF-16 या UTF-32

JSON may be represented using UTF-8, UTF-16, or UTF-32. When JSON 
    is written in UTF-8, JSON is 8bit compatible. When JSON is 
    written in UTF-16 or UTF-32, the binary content-transfer-encoding 
    must be used. 

"

" किसी भी चरित्र से बच गया हो सकता है। चरित्र बेसिक
बहुभाषी विमान (U + 0000 U + FFFF के माध्यम से) में है, तो यह
एक छह चरित्र अनुक्रम के रूप में प्रतिनिधित्व किया जा सकता है: एक रिवर्स सोलिडस छोटा अक्षर यू, जिसके बाद से पीछा
चार हेक्साडेसिमल अंक
चरित्र के कोड बिंदु को एन्कोड करें। हेक्साडेसिमल अक्षरों ए
एफ ऊपरी या लोअरकेस हो सकता है। इसलिए, उदाहरण के लिए,
युक्त एक स्ट्रिंग केवल एक एकल रिवर्स ठोस वर्ण को
"\ u005C" के रूप में दर्शाया जा सकता है। "

आप इन को समझते हुए भी तो कुछ अन्य पारसर्स समीक्षा करते हैं और देखते हैं कि उनमें से कोई अनुरूपता परीक्षण किया है। अपने खुद के आवेदन के लिए इन उधार।

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

यदि आप इसे देखने की अनुमति देते हैं तो http://www.antlr.org/wiki/display/ANTLR3/JSON+Interpreter पर एएनटीएलआर का उपयोग कर एक JSON पार्सर जनरेटर है। मैंने अभी भी Parboiled parser-generator for JSON खोजा है। यदि एक पार्सर लिखने का आपका मुख्य कारण यह सीखना है कि यह कैसे करना है, तो यह शायद एक अच्छा प्रारंभिक बिंदु है।

यदि आपको अनुमति नहीं है (या नहीं चाहते हैं) एक पार्सर जनरेटर का उपयोग करें तो आपको अपना खुद का पार्सर बनाना होगा। यह आम तौर पर दो भागों में आता है:

एक लेक्सर/टोककेज़र। यह भाषा विशिष्टता में परिभाषित बुनियादी प्राइमेटिव को पहचानता है। इस मामले में इसे घुंघराले-ब्रैकेट, उद्धरण इत्यादि को पहचानना होगा। यह शायद संख्याओं का प्रतिनिधित्व भी करेगा।

एक AbstractSyntaxTree (http://en.wikipedia.org/wiki/Abstract_syntax_tree, एएसटी) जनरेटर। यहां आप अपने जेएसओएन के अमूर्तता का प्रतिनिधित्व करने वाले पेड़ को इकट्ठा करने के लिए कोड लिखते हैं (उदाहरण के लिए व्हाइटस्पेस और कर्ली को त्याग दिया गया है)।

जब आपके पास एएसटी है तो इसे नोड्स पर फिर से चालू करना और वांछित आउटपुट बनाना आसान होना चाहिए।

लेकिन जेएसओएन जैसी साधारण भाषा के लिए पार्सर जेनरेटर लिखना बहुत काम है।

+0

एएनटीएलआर का नुकसान यह है कि यह निर्माण प्रक्रिया को बहुत जटिल बनाता है, हालांकि। Parboiled कोई नुकसान नहीं है! दयालु है कि यह पर्याप्त रूप से पर्याप्त नहीं है। – fge

+0

@fge सहमत हुए। मैं देखूंगा। –

4

यदि आपका "JSON" वास्तव में ऐसा है, तो आपको पहले बेसबॉल बल्ले लेना चाहिए और उसके निर्माता को सिर पर दस्तक देना चाहिए। गंभीरता से। (? क्यों):

public interface MyParser 
{ 
    boolean parse() 
     throws MyParsingException; 
    MyParser next(); 
} 

क्रियान्वयन तो एक CharBuffer एक तर्क के रूप और एक नक्शा बिल्डर ले जाएगा

तुम सच में अपने स्वयं के वर्ग लिखने पर जोर देते हैं हैं, तो आप उदाहरण के लिए इस तरह एक अंतरफलक का उपयोग कर सकते कक्षा; और पार्स करने के लिए आप क्या करेंगे:

final CharBuffer buf = CharBuffer.wrap(yourSource); 
final MyMapBuilder builder = new MyMapBuilder(); 

MyParser parser = new OpenBracketParser(buf, builder); 

while (parser.parse()) 
    parser = parser.next(); 

// result is builer.build() 

यह लेकिन एक उदाहरण है ...

दूसरा समाधान, आप एक मौजूदा पार्स उपकरण का उपयोग करना चाहते हैं; इस मामले में Parboiled पर एक नज़र डालें। जब आप शुद्ध जावा में अपने व्याकरण लिखते हैं तो एंटर, जेएफएक्स या अन्य से अधिक उपयोग करना आसान होता है।

अंत में

, अगर आप तय करते हैं कि पर्याप्त पर्याप्त है, और एक JSON पुस्तकालय उपयोग करने का निर्णय (आप वास्तव में क्या करना चाहिए कि), Jackson के साथ जाने के जो भी इस तरह के विकृत JSON पढ़ सकते हैं:

public static void main(final String... args) 
    throws IOException 
{ 
    final ObjectMapper mapper = new ObjectMapper() 
     .configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true) 
     .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); 

    final JsonNode node = mapper.readTree("{name: 'John'}"); 
    System.out.println(node); // {"name":"John"} 
} 
+0

उन्होंने कहा कि कोई पुस्तकालय नहीं है। – BLaZuRE

+1

उह ... ठीक है, प्रत्येक जहर के लिए, मुझे लगता है ... – fge

0
public abstract class AbstractMessageObject { 
    public String toString() { 
    Gson gson = new Gson(); 
    //here mapping Object class name is prefixed to json message so otherwise knows the mapping object 
    return "^" + this.getClass().getName() + "^" + gson.toJson(this); 
    } 
} 

आप इस AbstractMessageObject बढ़ा कर किसी भी सेम बना सकते हैं। जब भी आप उस ऑब्जेक्ट को जेसन पर पार्स करना चाहते हैं तो आपको केवल toString विधि

+1

ओपी ने कोई पुस्तकालय निर्दिष्ट नहीं किया :-( –

3

पर कॉल करने की आवश्यकता है, मैंने पहले एक लिखा है।चरण:

  1. JSON टेक्स्ट का प्रतिनिधित्व करने वाली स्ट्रिंग लें।

  2. एक जेसन टोकन क्लास बनाएं। मैं अपने जेटोकन को बुलाता हूं।

  3. चरण # 1 से पूरे पाठ पर जाएं और JToken (ओं) को पार्स करें।

  4. पुनरावर्ती समूह और अपने JToken (ओं) घोंसला।

  5. इसे सरल और वर्दी रखने का प्रयास करें। सभी जेटोकन नोड्स में एक बाल सरणी होती है जिसमें 0 या अधिक बच्चे हो सकते हैं। अगर नोड सरणी है, सरणी के रूप में ध्वज। नोड के बच्चों के लिए चाइल्ड सरणी का उपयोग ऑब्जेक्ट या आर््रे है। एकमात्र चीज जो बदलती है वह है जिसे इसे ध्वजांकित किया जाता है। सभी मानों को स्ट्रिंग प्रकार के रूप में भी रखें। इस तरह आपको बस "मूल्य" नामक नोड पर एक सदस्य की आवश्यकता होती है जिसे सभी कड़ी मेहनत के बाद सही डेटा प्रकार के रूप में व्याख्या किया जा सकता है।

  6. रक्षात्मक कोडिंग और यूनिट परीक्षणों का उपयोग करें। पार्सर के सभी घटकों के लिए परीक्षण लिखें। एक पारानोइड फैशन में कोड लिखने के लिए अतिरिक्त 3 घंटे बिताने के लिए बेहतर है, जहां आप मानते हैं कि आप बग्स को शिकार करने में 3 घंटे खर्च करने के बजाय हर सेकेंड में गलतियां कर रहे हैं। कोड परावर्तित पर्याप्त है, और आप डीबगिंग करते समय बहुत ही कम समय में निराश हो जाएंगे।

उदाहरण कोड: जब मैं एक आसान (विडंबना यह है कि) code-eval.com पर चुनौती कर रहा था। एक जेसन मेनू पार्सिंग चुनौती थी। मैंने सोचा कि यह किसी भी अंतर्निहित कार्यों का उपयोग करने के लिए धोखा दे रहा है, क्योंकि मेरे लिए कोड चुनौतियों का पूरा बिंदु आपकी एल्गोरिदम समस्या सुलझाने की क्षमताओं का परीक्षण करना है। चुनौती यहाँ है: https://www.codeeval.com/open_challenges/102/

मेरे कोड, कि इस चुनौती से गुजरता है, जावास्क्रिप्ट में एक पार्सर खरोंच से बनाया का उपयोग कर:

CODE: https://pastebin.com/BReK9iij 
Was not able to post it on stack-overflow because it is too much code. 
Put it in a non-expiring paste-bin post. 

नोट: यह कोड कुछ सुधार इस्तेमाल कर सकते हैं। इसमें से कुछ बहुत अक्षम हैं और यह यूनिकोड के साथ काम नहीं करेगा।

मैं अपने स्वयं के JSON पार्सर को लिखने की अनुशंसा नहीं करता जबतक कि आप किसी प्रकार के गैर-मानक तरीके से JSON की व्याख्या नहीं कर रहे हैं।

उदाहरण के लिए: मैं वर्तमान में टेक्स्ट-आधारित साहसिक के लिए शाखाओं को व्यवस्थित करने के लिए JSONedit का उपयोग कर रहा हूं। मैं केवल जेएसओएन फ़ाइल प्रारूप का उपयोग कर रहा हूं क्योंकि यह कॉम्पैक्ट है और दर्शक मुझे वस्तुओं का विस्तार और अनुबंध करने की अनुमति देता है। गोलांग के साथ आने वाला मानक पार्सर उस तरीके की व्याख्या नहीं करता जिस तरह से मैं इसे समझना चाहता हूं, इसलिए मैं अपना खुद का पार्सर लिख रहा हूं।

संबंधित मुद्दे