2009-11-21 14 views
18

समस्या का सामना करना पड़ रहा है यह है कि ऑब्जेक्ट्स की एक बड़ी सूची को एक एक्सएमएल फ़ाइल में कैसे मार्शल करना है, इतना बड़ा है कि मैं एक ही चरण में पूरी सूची को मार्शल नहीं कर सकता। मेरे पास एक तरीका है जो इन ऑब्जेक्ट्स को खंडों में वापस लाता है, लेकिन फिर मैं इन्हें जेएक्सबी का उपयोग करके मार्शल करता हूं, मार्शलर एक अपवाद के साथ लौटता है कि ये ऑब्जेक्ट्स रूट तत्व नहीं हैं। सामान्य मामले के लिए यह ठीक है कि आप एक ही चरण में पूरे दस्तावेज़ को मार्शल करना चाहते हैं, लेकिन यह तब भी होता है जब मैं JAXB_FRAGMENT प्रॉपर्टी को सत्य पर सेट करता हूं।जेएक्सबी मार्शलर का उपयोग करके बड़ी फ़ाइलों को कैसे स्ट्रीम करें?

यह वह जगह है वांछित XML आउटपुट:

<rootElem> 
    <startDescription></startDescription> 
    <repeatingElem></repeatingElem> 
    <repeatingElem></repeatingElem>... 
</rootElem> 

तो मैं मुझे लगता है कि गतिशील repeatingElements के अगले हिस्सा लोड करता है marshaller करने के लिए इसे खिलाने के लिए श्रोता किसी तरह की जरूरत है इससे पहले कि वह के बंद टैग लिखते थे मान rootElement। लेकिन यह कैसे करें? अब तक मैंने केवल छोटी फ़ाइलों को मार्शल करने के लिए जेएक्सबी का उपयोग किया है और जेएक्सबी दस्तावेज उस उपयोग के मामले के लिए ज्यादा संकेत नहीं देता है।

उत्तर

-8

मुझे जेएक्सबी का अधिक पता नहीं है, इसलिए मैं मदद नहीं कर सकता। लेकिन अगर आपको कोई फर्क नहीं पड़ता, तो मेरे पास एक सुझाव है।

लेखन XML इसे पढ़ने से बहुत आसान है, इसलिए आपकी समस्या का समाधान अधिक "निम्न स्तर" दृष्टिकोण का उपयोग करना हो सकता है। एक्सएमएल के लिए उपलब्ध ओपन सोर्स लाइब्रेरी में से एक का उपयोग करके बस अपना खुद का मार्शलर लिखें। मुझे लगता है कि आप dom4j का उपयोग करके आसानी से ऐसा कर सकते हैं।

9

जैसा कि आपने पाया है, यदि किसी वर्ग में @XmlRootElement एनोटेशन नहीं है, तो आप उस वर्ग का उदाहरण मार्शलर को पास नहीं कर सकते हैं। हालांकि, इसके चारों ओर एक आसान तरीका है - ऑब्जेक्ट को JAXBElement में लपेटें, और इसके बजाय मार्शलर को पास करें।

अब JAXBElement एक बदसूरत जानवर है, लेकिन यह उस वस्तु का तत्व नाम और नामस्थान है जिसमें आप मार्शल करना चाहते हैं, जो जानकारी आमतौर पर @XmlRootElement एनोटेशन में निहित होगी। जब तक आपके पास नाम और नामस्थान हो, तब तक आप अपने POJO को लपेटने के लिए JAXBElement बना सकते हैं, और मार्शल।

यदि आपके पीओजेओ एक्सजेसी द्वारा उत्पन्न किए गए थे, तो यह ObjectFactory कक्षा भी उत्पन्न करेगा जिसमें आपके लिए JAXBElement रैपर बनाने के लिए कारखाने के तरीके शामिल हैं, जिससे चीजें थोड़ा आसान हो जाती हैं।

आपको अभी भी दोहराए गए आंतरिक तत्वों के लिए JAXB_FRAGMENT संपत्ति का उपयोग करना होगा, अन्यथा जेएक्सबी प्रत्येक बार एक्सएमएल प्रोलॉग जैसी चीजें उत्पन्न करेगा, जो आप नहीं चाहते हैं।

15

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मैं एक और समान प्रश्न के डुप्लीकेट खोजने के दौरान इसे पार कर गया।

जैसा कि @ स्काफमैन सुझाव देता है, आप JAXB_FRAGMENT सक्षम के साथ मार्शल चाहते हैं और आपकी ऑब्जेक्ट्स JAXBElement में लिपटे हैं। फिर आप दोहराए गए तत्व के प्रत्येक व्यक्तिगत उदाहरण को बार-बार मार्शल करते हैं। असल में ऐसा लगता है कि आप इस तरह मोटे तौर पर कुछ चाहते हैं:

public class StreamingMarshal<T> 
{ 
    private XMLStreamWriter xmlOut; 
    private Marshaller marshaller; 
    private final Class<T> type; 

    public StreamingMarshal(Class<T> type) throws JAXBException 
    { 
     this.type = type; 
     JAXBContext context = JAXBContext.newInstance(type); 
     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
    } 

    public void open(String filename) throws XMLStreamException, IOException 
    { 
     xmlOut = XMLOutputFactory.newFactory().createXMLStreamWriter(new FileOutputStream(filename)); 
     xmlOut.writeStartDocument(); 
     xmlOut.writeStartElement("rootElement"); 
    } 

    public void write(T t) throws JAXBException 
    { 
     JAXBElement<T> element = new JAXBElement<T>(QName.valueOf(type.getSimpleName()), type, t); 
     marshaller.marshal(element, xmlOut); 
    } 

    public void close() throws XMLStreamException 
    { 
     xmlOut.writeEndDocument(); 
     xmlOut.close(); 
    } 
} 
+0

कन्स्ट्रक्टर में मार्शलर सेट करने की आवश्यकता है। this.marshaller = मी; –

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