SAX字符缓冲区大小

时间:2013-09-30 07:03:07

标签: java xml parsing sax saxparser

我正在尝试使用Sax来解析非常大的XML文件。 100的megs。 问题是Parser一次读取正好2048个字符并终止。我使用回调“public void characters(...)”将标签的值分为两部分。例如,第一部分位于具有长度的位置2044上的字符数组中 4“2013”​​和第二部分“-09-30”在0号位置,长度为6.它应该是一个日期 如果在一个部分中收到,则为“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;
    }
    }
    }
    }

2 个答案:

答案 0 :(得分:6)

这就是SAX解析器的工作方式。如果你可以增加缓冲区大小(我不知道如何做到这一点),它将无济于事;它只会减少你将价值分成碎片的次数。

SAX解析器可以在任何需要的地方(documentation)自由分割字符串。它这样做是为了提高效率;避免使用记忆;为了简化实施;或者图书馆开发人员提出的任何其他原因。

因此,如果你想把你的琴弦整理成一片,你需要自己动手。一个简单的解决方案,假设您永远不需要使用子元素累积字符串值:

  • 在您的实现类中添加StringBuffer accumulator,以及isAccumulating标志。
  • startElement中,如果感兴趣的是元素,请设置isAccumulating标记。
  • characters中,如果设置了isAccumulating标志,则将字符附加到累加器。
  • endElement中,如果设置了isAccumulating标志,请对累积的字符串执行任何操作,然后清除该标志并清空缓冲区。

如果您可能需要使用子元素收集值,则可以将isAccumulating从标志更改为整数深度计数器。如果计数器大于0,则startElement递增计数器;如果元素需要收集其值,则将其设置为1。如果计数器大于0,则characters附加字符。endElement如果计数器大于零则递减计数器,如果结果为0,则处理然后清除累加器。

答案 1 :(得分:0)

使用String.trim()并检查String.length()>=0,然后再继续进入characters()功能

并使用stack跟踪cData所属的标记。然后你可以append到它。

相关问题