1

非常に大きな XML ファイルを解析するために Sax を使用しようとしています。数百メガ。問題は、パーサーが一度に正確に 2048 文字を読み取って終了することです。コールバック「public void characters(...)」を使用して、2 つの部分に分割されたタグの値を取得します。たとえば、最初の部分は文字配列の位置 2044 で長さ 4 "2013" で、2 番目の部分は位置 0 で長さ 6 の "-09-30" です。これは日付値 "2013-09-30" である必要があります。一部で受け取る場合。どうすればこの分割を回避できますか? 誰でも私を助けることができますか?

    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;
    }
    }
    }
    }
4

2 に答える 2

6

これはまさに SAX パーサーが機能する方法です。バッファ サイズを増やすことができたとしても (その方法はわかりません)、役に立ちません。値を細かく分割する回数を減らすだけです。

SAX パーサーは、必要に応じて文字列を自由に分割できます (ドキュメント)。これは効率のために行われます。メモリの使用を避けるため。実装を簡単にするため。または、ライブラリ開発者が思いついたその他の理由。

したがって、弦を 1 つにまとめたい場合は、自分で行う必要があります。サブ要素で文字列値を蓄積する必要がないと仮定した場合の簡単な解決策:

  • を実装クラスに追加StringBuffer accumulatorし、isAccumulating フラグも追加します。
  • startElement、要素に関心がある場合は、isAccumulatingフラグを設定します。
  • charactersisAccumulatingフラグが設定されている場合、文字をアキュムレータに追加します。
  • endElementisAccumulatingフラグが設定されている場合は、蓄積された文字列に対して必要なことをすべて行ってから、フラグをクリアしてバッファを空にします。

サブ要素で値を収集する必要がある場合はisAccumulating、フラグから整数の深度カウンターに変更できます。startElementカウンタが 0 より大きい場合はインクリメントし、要素の値を収集する必要がある場合はカウンタを 1 に設定します。charactersカウンタが 0 より大きい場合は文字を追加します。カウンタが 0 より大きい場合はカウンタをendElementデクリメントし、結果が 0 の場合はアキュムレータを処理してからクリアします。

于 2013-09-30T15:39:18.487 に答える