2013-02-28 22 views
11
में बड़े XML दस्तावेज़ों

मैं है निम्नलिखित समस्या:पार्सिंग जावा

मैं एक XML फ़ाइल (लगभग 1 जीबी) मिल गया है, और ऊपर पुनरावृति करने के लिए है और नीचे (यानी अनुक्रमिक नहीं; एक के बाद एक) के क्रम में आवश्यक डेटा प्राप्त करने और उस पर कुछ संचालन करने के लिए। प्रारंभ में, मैंने डोम जावा पैकेज का उपयोग किया, लेकिन जाहिर है, एक्सएमएल फाइल के माध्यम से पार्स करते समय, जेवीएम अपनी अधिकतम ढेर स्पेस तक पहुंचता है और रुक जाता है।

इस समस्या को दूर करने के लिए, मैं जिन समाधानों के साथ आया था, उन्हें एक और पार्सर ढूंढना था जो एक्सएमएल में प्रत्येक तत्व को पुन: सक्रिय करता है और फिर मैं अपनी हार्ड डिस्क पर अस्थायी SQLite डेटाबेस में इसकी सामग्री संग्रहीत करता हूं। इसलिए, इस तरह, JVM का ढेर पार नहीं हुआ है, और एक बार सभी डेटा भरने के बाद, मैं XML फ़ाइल को अनदेखा करता हूं और अस्थायी SQLite डेटाबेस पर अपने परिचालन जारी रखता हूं।

क्या कोई और तरीका है कि मैं अपनी समस्या से कैसे निपट सकता हूं?

+1

xml – Biswajit

+1

पार्स करने के लिए जैक्सबी का उपयोग करें जैसा कि अन्य ने कहा है कि आपको एक डोम पार्सर के बजाय एक SAX पार्सर का उपयोग करने की आवश्यकता है, यह वही करेगा जो आपको चाहिए। इसे पढ़ें: http://stackoverflow.com/questions/6828703/difference-about-sax-and-dom – cowls

+0

यदि आप पूरे डोम पेड़ को नहीं पकड़ सकते हैं, तो आपको अनुक्रमिक रूप से अपनी प्रसंस्करण करने का एक तरीका ढूंढना होगा। क्या यह संभव है? क्या आप एक एक्सएसएलटी दिखा सकते हैं जो आपको चाहिए? –

उत्तर

12

SAX (Simple API for XML) आपकी यहां सहायता करेगा।

डोम पार्सर के विपरीत, SAX पार्सर XML दस्तावेज़ की एक में स्मृति प्रतिनिधित्व का निर्माण नहीं करता है और इसलिए तेजी से होता है और कम स्मृति का उपयोग करता है। इसके बजाय, एसएएक्स पार्सर ने एक्सएमएल दस्तावेज़ संरचना के क्लाइंट को कॉलबैक का आह्वान करके सूचित किया है, यानी org.xml.sax.helpers.DefaultHandler पार्सर को प्रदान किए गए उदाहरण पर विधियों का आह्वान करके। जब दस्तावेज़/तत्व के प्रारंभ/समाप्ति तरह की घटनाओं उत्पन्न कर रहे हैं

SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 
DefaultHandler handler = new MyHandler(); 
parser.parse("file.xml", handler); 

कहाँ MyHandler में आप कार्यों को निर्धारित लिया जाना:

यहाँ एक उदाहरण दिया गया है।

class MyHandler extends DefaultHandler { 

    @Override 
    public void startDocument() throws SAXException { 
    } 

    @Override 
    public void endDocument() throws SAXException { 
    } 

    @Override 
    public void startElement(String uri, String localName, String qName, 
      Attributes attributes) throws SAXException { 
    } 

    @Override 
    public void endElement(String uri, String localName, String qName) 
      throws SAXException { 
    } 

    // To take specific actions for each chunk of character data (such as 
    // adding the data to a node or buffer, or printing it to a file). 
    @Override 
    public void characters(char ch[], int start, int length) 
      throws SAXException { 
    } 

} 
+2

यदि आपने कभी भी सैक्स पार्सिंग किया है, तो आप शायद जानते हैं कि 'अक्षर()' विधि भी बहुत महत्वपूर्ण है, और आपको चरित्र डेटा के ** बफरिंग ** करना है, क्योंकि यह गारंटी नहीं है कि सामग्री डेटा संभाला जाता है एक ब्लॉक में (यानी, दो 'वर्ण()' कॉल तुरंत किया जा सकता है)। मुझे लगता है कि यह उल्लेख करने लायक है। – gaborsch

+1

मेरा मतलब यह नहीं था कि मेरा समाधान पूरा हो। यह केवल एक प्राथमिक कार्यान्वयन था। हालांकि इंगित करने के लिए धन्यवाद। मैं इसके साथ अपना जवाब अपडेट करूंगा। –

+0

अच्छा, धन्यवाद, इस तरह यह +1 है – gaborsch

3

आप मेमरी सीमा को मानने के लिए नहीं करना चाहते हैं, मैं निश्चित रूप से आप अपने वर्तमान दृष्टिकोण का उपयोग करने, और डेटाबेस में सब कुछ की दुकान सलाह देते हैं।

एक्सएमएल फ़ाइल का विश्लेषण SAX parser द्वारा किया जाना चाहिए, क्योंकि सभी ने सिफारिश की है (मुझे सहित)। इस तरह आप एक समय में एक वस्तु बना सकते हैं, और आप इसे तुरंत डेटाबेस में बना सकते हैं।

पोस्ट-प्रोसेसिंग (क्रॉस-रेफरेंस को हल करने) के लिए, आप डेटाबेस से SELECT एस का उपयोग कर सकते हैं, प्राथमिक कुंजी, इंडेक्स आदि बना सकते हैं। आप ORM (Eclipselink, Hibernate) का उपयोग कर सकते हैं, साथ ही यदि आप इससे सहज महसूस करते हैं ।

वास्तव में मैं वास्तव में SQLite की अनुशंसा नहीं करता हूं, एक MySQL सर्वर स्थापित करना और डेटा को स्टोर करना आसान है। बाद में आप एक्सएमएल डेटा का पुन: उपयोग भी कर सकते हैं (यदि आप हटा नहीं पाते हैं)।

+0

मुझे आश्चर्य है कि कोई कैसे विश्वास कर सकता है कि एक एम्बेडेड डेटाबेस का उपयोग करने के बजाय एक संपूर्ण डेटाबेस सर्वर स्थापित करना आसान है, जहां आपको केवल कुछ स्थापित करने के बिना एक JAR फ़ाइल शामिल करना है। मुझे लगता है कि इस प्रयोग के लिए एक अलग डेटाबेस सर्वर ओवरकिल होगा। हो सकता है कि डेटाबेस सर्वर का उपयोग करने के कुछ और अच्छे कारण हैं, लेकिन सेटअप करना आसान है? वास्तव में? – vanje

+0

@vanje मेरा मतलब ओरेकल नहीं था :) हम MySQL के बारे में बात कर रहे हैं। गंभीरता से, मुझे विश्वास नहीं है कि किसी भी डेवलपर के लिए एक MySQL सर्वर स्थापित करने में समस्या होगी। – gaborsch

+0

मुझे लगता है कि प्रत्येक डेवलपर ओरेकल और MySQL दोनों की मूल स्थापना करने में सक्षम होना चाहिए। और मैं आपसे सहमत हूं कि ओरेकल MySQL से कहीं अधिक जटिल है। लेकिन यह बात नहीं है। आपने MySQL को SQLite के साथ तुलना की और कहा कि MySQL सेटअप करना आसान होगा। लेकिन आपने यह नहीं बताया कि आपकी राय पर वास्तव में क्या आसान है। – vanje

1

यदि आप SAX से उच्च स्तर के दृष्टिकोण का उपयोग करना चाहते हैं, जो प्रोग्राम के लिए बहुत मुश्किल हो सकता है, तो आप हाल ही में सैक्सन-ईई रिलीज का उपयोग करके एक्सएसएलटी ट्रांसफॉर्मेशन स्ट्रीमिंग देख सकते हैं। हालांकि, आप सटीक प्रसंस्करण के बारे में बहुत अस्पष्ट हैं कि आप यह जानकर कर रहे हैं कि यह आपके विशेष मामले के लिए काम करेगा या नहीं।

0

अगर आप को संभालने के लिए एक संसाधन के अनुकूल दृष्टिकोण की आवश्यकता बहुत बड़ी एक्सएमएल इस प्रयास करें: http://www.xml2java.net/xml-to-java-data-binding-for-big-data/ तो यह आपको एक SAX तरह से डेटा की प्रक्रिया करने की अनुमति देता है, लेकिन उच्च स्तर की घटनाओं में हो रही (xml डेटा जावा पर मैप किया गया) का लाभ के साथ और इन वस्तुओं के साथ सीधे अपने कोड में काम करने में सक्षम होने के नाते।इसलिए यह जैक्सबी सुविधा और SAX संसाधन अनुकूलता को जोड़ती है।

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