sax parser stringbuilder возвращает только одну строку

Я пытался использовать именованный объект StringBuilder, но все еще не получаю все CDATA из тега описания. XML находится на Events-Ovations365:

В основном он получает CDATA только в одной строке:

img: http://www.ovations365.com/sites/ovations365.com/images/org/81/newtown_medium.jpg

alt="Перерезание ленты "Тропа наследия Окмалги"">

package com.example.ovations_proj;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

import com.example.ovations_proj.RssItem;


public class RssParseHandler extends DefaultHandler {

    private List<RssItem> rssItems;

    // Used to reference item while parsing
    private RssItem currentItem;

    // Parsing title indicator
    private boolean parsingTitle; 
    // Parsing link indicator
    private boolean parsingLink; 
    private boolean parsingDes;

    StringBuilder obj;


    public RssParseHandler() {
        rssItems = new ArrayList<RssItem>();
    }

    public List<RssItem> getItems() {
        return rssItems;
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        System.out.println("Start Element :" + qName);
        if ("item".equals(qName)) { //item
            currentItem = new RssItem();
        }else if ("description".equals(qName) ) { //description
            obj = new StringBuilder();
            parsingDes = true;
        }

    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        System.out.println("End Element :" + qName);
        if ("item".equals(qName)) {
            rssItems.add(currentItem);//item
            currentItem = null;         
        } else if ("description".equals(qName)) {   //description           
            String theFullText = obj.toString();
            System.out.println("fulltext data:  "  + theFullText);
            parsingDes = false;         
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (parsingTitle) {
            if (currentItem != null){
                currentItem.setTitle(new String(ch, start, length));                
            }
        } else if (parsingDes) {       
            if (currentItem != null && obj!=null ) {                                
                obj.append(ch, start, length);  
                parsingDes = false;
            }
        }
    }
}

person user2230114    schedule 02.04.2013    source источник


Ответы (2)


Вероятно, это связано с тем, что вы неправильно реализуете метод символов, см. учебник Oracle< /а>:

Парсеры не обязаны возвращать какое-то конкретное количество символов за один раз. Анализатор может возвращать что угодно, от одного символа за раз до нескольких тысяч, и при этом оставаться реализацией, соответствующей стандарту. Поэтому, если вашему приложению необходимо обработать символы, которые оно видит, разумно использовать метод character() для накопления символов в java.lang.StringBuffer и работы с ними только тогда, когда вы уверены, что все они были найдены.

Ваш код предполагает, что вы получаете весь текст для элемента за один вызов, но это не гарантируется. Метод символов должен накапливать найденный текст в StringBuffer (или StringBuilder, или другую структуру данных), но решения о том, что делать с накопленным текстом, должны приниматься где-то еще, например, в методе endElement. Похоже, вы преждевременно устанавливаете флаг в методе символов и приводите к потере остального текста.

person Nathan Hughes    schedule 02.04.2013
comment
Я все еще немного смущен. Как я неправильно использую свой StringBuffer? - person user2230114; 02.04.2013
comment
@ user2230114: символы можно вызывать несколько раз, вы можете получить первую часть строки в одном вызове и вторую часть строки в другом вызове. поэтому, если вы установите флаг на основе того, что получили что-то, вы можете потерять все оставшиеся вещи. Добавьте строку отладки, распечатывающую то, что вы получаете в методе символов. - person Nathan Hughes; 02.04.2013
comment
Спасибо, Натан, который решил это. - person user2230114; 03.04.2013

Вот что сработало для меня с кодом, который испортил его, прокомментировал. Мой флаг parsingDes вызывал только одно добавление.

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
    if (parsingTitle) {
        if (currentItem != null){
            currentItem.setTitle(new String(ch, start, length));                
        }
    } else if (parsingLink) { 
        if (currentItem != null) {
            currentItem.setLink(new String(ch, start, length));
            parsingLink = false;
        }
    } else if (parsingDes) {       
        if (currentItem != null){// && obj!=null ) {
            obj.append(ch, start, length);
            //parsingDes = false;
        }
    }
person user2230114    schedule 02.04.2013