2013-09-30 48 views
1

我想使用Sax來解析非常大的XML文件。百萬的megs。 問題是解析器一次只能讀取2048個字符並終止。我使用回調「public void characters(...)」得到了標籤值的分解成兩部分的問題。例如,第一部分位於位置2044上的字符數組中,長度爲 4「2013」​​,位置0上的第二部分爲「-09-30」,長度爲6.它應該是日期 值「2013-09- 30「,如果在一個部分接收。 何我可以避免這種分裂?任何人都可以幫助我?SAX字符緩衝區大小

public void characters(char[] ch, int start, int length) throws SAXException { 
    if (Main.errorProceso==0){ 
    for(int i=0;i < strlista.size();i++){ 
    if(strlista.get(i).equals(sEtiqueta_actual)){ 
    if (sEtiqueta_actual.equals("Root.Header.Body.")){ 
    String FileNm= String.valueOf(ch, start, length); 
    if (!FileNm.substring(0,2).equalsIgnoreCase("XX")){ 
    logger.info("El identificador no es XX"); 
    Main.errorProceso=1; 
    i=strlista.size()+1; 
    sEtiqueta_actual=""; 
    } 
    else{ 
    sCod_Fichero=FileNm.substring(0,2)+XXteFormat.format(XXte); 
    } 
    } 
    else if (sEtiqueta_actual.equals("Root.Header.Date.")){ 
    String aux = String.valueOf(ch, start, length).split("T")[0]; 
    try { 
    sFec=newFormat.format(oldFormat.parse(aux)); 
    } catch (ParseException e) { 
    logger.error(e.getLocalizedMessage()); 
    Main.errorProceso=1; 
    } 
    } 
    else if (sEtiqueta_actual.equals("Root.Header2.Body2.")){ 
    sNum_Total=String.valueOf(ch, start, length); 
    } 
    else if (sEtiqueta_actual.equals("Root.Header3.Body3.Spcf.Inst.")){ 
    sImp =String.valueOf(ch, start, length); 
    } 
    . 
    . 
    . 
    else if (sEtiqueta_actual.equals("Root.Header3.Body3.Spcf.Req.")){ 
    try { 
    sFec2=newFormat.format(oldFormat.parse(String.valueOf(ch, start, length))); 
    } catch (ParseException e) { 
    logger.error(e.getLocalizedMessage()); 
    Main.errorProceso=1; 
    } 
    } 
    } 
    } 
+0

你的代碼在哪裏? –

+0

@VimalBera我的代碼 – user2830209

回答

6

這只是SAX解析器的工作方式。如果你可以增加緩衝區的大小(我不知道該怎麼做),它不會有幫助;它只會減少你將值分解成塊的次數。

SAX解析器可以隨意將字符串分開(documentation)。它是爲了提高效率;避免使用內存;爲簡化實施;或者圖書館開發人員提出的任何其他原因。

所以,如果你想讓你的字符串在一塊,你需要自己做。一個簡單的解決方案,假設你永遠需要與子元素積累字符串值:

  • 添加StringBuffer accumulator到您的實現類,以及一個isAccumulating標誌。
  • startElement中,如果元素感興趣,請設置isAccumulating標誌。
  • characters中,如果設置了isAccumulating標誌,則將字符追加到累加器。
  • endElement,如果設置了isAccumulating標誌,則對累積字符串做所需的任何操作,然後清除標誌並清空緩衝區。

如果您可能需要使用子元素收集值,則可以將isAccumulating從標誌更改爲整數深度計數器。 startElement如果計數器大於0,則遞增計數器;如果元素需要收集其值,則將其設置爲1。如果計數器大於0,則characters附加字符。endElement如果計數器大於零,則遞減計數器,如果結果爲0,則處理並清除累加器。

+0

有趣,+1。我想知道,你碰巧知道StAX是否也是如此? –

+0

@BoristheSpider:我從來沒有使用StAX,但我的印象是,它爲你收集字符串。 「拉」界面當然使這更實用。快速瀏覽他們的主頁沒有透露太多文檔,所以我沒有進一步追求。 – rici

+0

@rici:非常感謝。在閱讀您的消息之前,我已經找到了關於StringBuffer的一些信息,並且我在您的回覆中對我進行了評論,並編寫了類似的內容。我今天試了一下,似乎工作正常! – user2830209

0

使用String.trim(),並進一步前進到characters()功能

前檢查String.length()>=0並使用stack跟蹤哪個標籤的cData屬於。然後你可以append它。