2013-09-30 3 views
1

저는 Sax를 사용하여 매우 큰 XML 파일을 구문 분석하려고합니다. 100의 megs. 문제는 Parser가 한 번에 정확히 2048자를 읽고 종료합니다. 콜백 "공개 무효 문자 (...)"를 사용하여 두 부분으로 분리 된 태그 값을 잃게됩니다. 예를 들어 첫 번째 부분은 위치가 2044 인 문자 배열에 4 "2013"이고 두 번째 부분은 길이가 0 인 위치에 "-09-30"입니다. 문자는 값이 "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). 효율성을 위해이 작업을 수행합니다. 메모리 사용을 피하십시오. 시행의 단순화를 위해; 또는 도서관 개발자가 생각한 다른 이유가 무엇이든간에.

문자열을 하나의 조각으로 가져 오려면 직접해야합니다. 간단한 해결책은 당신이 하위 요소 문자열 값을 축적 할 필요가 없습니다 가정 :

  • 이 구현 클래스뿐만 아니라 isAccumulating 플래그에 StringBuffer accumulator를 추가합니다.
  • startElement에서 해당 요소가 관심 대상이면 isAccumulating 플래그를 설정하십시오.
  • 플래그가 설정된 경우 characters에 문자를 누적기에 추가하십시오.
  • endElement 플래그에 isAccumulating 플래그가 설정되어 있으면 누적 된 문자열로 수행해야하는 작업을 수행 한 다음 플래그를 지우고 버퍼를 비 웁니다.

하위 요소가있는 값을 수집해야 할 수도있는 경우 isAccumulating을 플래그에서 정수 깊이 카운터로 변경할 수 있습니다. startElement은 카운터가 0보다 크면 카운터를 증가 시키거나 요소가 값을 수집해야하는 경우 1로 설정합니다. characters은 카운터가 0보다 큰 경우 문자를 추가합니다. endElement은 카운터가 0보다 큰 경우 카운터를 감소시키고 결과가 0이면 누적기를 처리 한 다음 지 웁니다.

+0

흥미 롭군요, +1. 궁금한 점이 있습니까? StAX가 사실인지 알게됩니까? –

+0

@BoristheSpider : 나는 StAX를 한번도 사용하지 못했지만 내 인상은 문자열을 수집한다는 것입니다. "끌어 오기"인터페이스를 사용하면 더욱 실용적입니다. 홈페이지를 빨리 둘러보고 많은 문서를 공개하지 않았으므로 더 이상 추구하지 않았습니다. – rici

+0

@rici : 대단히 감사합니다. 귀하의 메시지를 읽기 전에, 나는 이미 StringBuffer에 관한 정보를 발견했으며 귀하의 응답에서 저에게 당신이 말한 것과 비슷한 것을 프로그래밍했습니다. 나는 오늘 그것을 시험해 보았다. 그리고 그것은 ok 일을 보인다! – user2830209

0

사용 String.trim()characters() 기능

로 더 진행하기 전에 String.length()>=0를 확인하고 cData이 속한 태그를 추적하기 위해 stack를 사용합니다. 그런 다음 append 수 있습니다.