2010-12-31 25 views
19

मैं XML से कुछ डेटा पार्स करने के लिए एक प्रोजेक्ट कर रहा हूं।जावा SAX पार्सर स्प्लिट अक्षरों को कॉल करता है()

उदाहरण के लिए, एक्सएमएल

<abc>abcdefghijklmno</abc> 

मैं "abcdefghijkmnlp" पार्स करने के लिए की जरूरत है।

लेकिन जब मैं अपने पार्स का परीक्षण, मैं एक बड़ी समस्या की खोज:

public class parser{ 
    private boolean hasABC = false; 


     //Constructor HERE 
     ...................... 
     ...................... 

    @Override 
    public void startDocument() throws SAXException{ 
    } 

    @Override 
    public void endDocument() throws SAXException{ 
    } 

    @Override 
    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException{ 
      if ("abc".equalsIgnoreCase(localName)) { 
       this.hasABC = true; 
      } 
     } 
     @Override 
     public void endElement(String namespaceURI, String localName, String qName) throws SAXException{ 
      if ("abc".equalsIgnoreCase(localName)) { 
       this.hasABC = false; 
      } 
     } 
     @Override 
     public void characters(char ch[], int start, int length){ 
      String content = new String(ch, start, length).trim(); 
      if(this.hasABC){ 
       System.out.println("ABC = " + content); 
      } 
     } 
    } 

मैं पता चलता है कि पार्सर टैग दो समय सिस्टम प्रिंट पार्स है बाहर है,

एबीसी = abcdefghi

एबीसी = jklmno < < ============ संदेश

विभाजित क्यों पार्सर ऑटो पात्रों को वापस कॉल करें() दो बार ????

क्या एक्सएमएल कुछ "\ n" या "\ r" ???

+0

हाय @ रेबेका, क्या आपको इस समस्या का समाधान मिला, मुझे एक ही समस्या का सामना करना पड़ रहा है। – Ramesh

उत्तर

32

पार्सर characters विधि को एक से अधिक बार कॉल कर रहा है, क्योंकि यह प्रति spec को अनुमति और अनुमति दे सकता है। यह तेजी से पार्सर में मदद करता है और उनकी स्मृति पदचिह्न कम रखता है। यदि आप एक सिंगल स्ट्रिंग चाहते हैं तो ऑब्जेक्ट startElement में ऑब्जेक्ट बनाएं और इसे endElement विधि पर संसाधित करें।

+0

हां, मैं charaters() में पाठ को संग्रहीत करने के लिए एक gobal चर का उपयोग कर रहा हूं और endElement() पर इस चर को मुद्रित करता हूं। – rebecca

+0

@rebecca प्रश्न से कोड स्निपेट ऐसा नहीं करता है, मुझे लगता है कि आप अब कुछ नए निश्चित कोड का जिक्र कर रहे हैं? :) – rogerdpack

7

आप आश्चर्यचकित होंगे लेकिन यह एक दस्तावेज व्यवहार है यानी आप यह नहीं मान सकते कि पार्सर एक कॉलबैक में किसी तत्व के सभी टेक्स्ट-डेटा को पढ़ और वापस कर देगा। मुझे पहले भी यही अनुभव था। आपको इस स्थिति को संभालने के लिए कोड करने की आवश्यकता है या आप Stax parser पर स्विच कर सकते हैं। एकाधिक कॉलबैक में डेटा जमा करने के लिए आप CharArrayWriter का उपयोग कर सकते हैं।

JavaDoc of ContentHandler.characters(...)

से नीचे देखें पार्सर रिपोर्ट चरित्र डेटा के प्रत्येक टुकड़ा के लिए इस विधि कॉल करेंगे। SAX पार्सर्स सभी संगत वर्ण डेटा को एक सिंगल खंड में वापस कर सकते हैं, या वे को कई हिस्सों में विभाजित कर सकते हैं; हालांकि, एकल ईवेंट में सभी वर्ण एक ही बाहरी इकाई से आते हैं ताकि लोकेटर उपयोगी जानकारी प्रदान करता हो।

+0

मैं वास्तव में चाहता हूं कि कुछ ध्वज * नहीं * ऐसा करें: | – rogerdpack

3

यह SAX की एक विशेषता है। पार्सर टेक्स्ट सेगमेंट को विभाजित कर सकता है और अपनी characters विधि को जितनी बार पसंद करता है उसे कॉल कर सकता है।

इसका कारण प्रदर्शन है, जो सैक्स उपयोग की आसानी से प्राथमिकता देता है। SAX ने अपने आंतरिक बफर का उपयोग किया हो ताकि प्रतिलिपि से बचने के लिए यह आपके कोड के माध्यम से अब तक डेटा पास कर सके।

4

आप की तरह शुरू, अंत और चरित्र-प्रक्रिया में परिवर्तन कर सकते हैं:

  • अंत विधि में "वैश्विक" सामग्री चर
  • तो शुरू विधि में यह शून्य (सामग्री == नल)
  • जोड़ने यू println या किसी वस्तु
  • चरित्र विधि में है कि सामग्री स्ट्रिंग जोड़ सकते हैं यू बना सकते हैं/बाकी:

    if (content == null) 
    { 
        content = new String(ch, start, length); 
    } else { 
        content += new String(ch, start, length); 
    } 
    

    क्रूर तरीका (स्ट्रिंगबिल्डर के साथ ऐसा करने के लिए बेहतर) लेकिन काम करता है और "स्ट्रिंग" अब विभाजित नहीं होता है।

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