sax parser stringbuilder only returning one line [

2019-03-03 04:28发布

This question already has an answer here:

I've tried using a StringBuilder named object, but I'm still not getting all the CDATA from the description tag.The xml is located at Events-Ovations365:

Basically it only gets the CDATA on one line:

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

alt="Ocmulgee Heritage Trail Ribbon Cutting">

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

2条回答
兄弟一词,经得起流年.
2楼-- · 2019-03-03 04:35

It's probably because you're not implementing the characters method correctly, see Oracle's tutorial:

Parsers are not required to return any particular number of characters at one time. A parser can return anything from a single character at a time up to several thousand and still be a standard-conforming implementation. So if your application needs to process the characters it sees, it is wise to have the characters() method accumulate the characters in a java.lang.StringBuffer and operate on them only when you are sure that all of them have been found.

Your code is assuming you're getting the entire text for an element in one call, but that's not guaranteed. The characters method needs to accumulate the text found into a StringBuffer (or StringBuilder or other data structure), but the decisions on what to do with the accumulated text need to be somewhere else, such as in the endElement method. It looks like you are setting a flag prematurely in the characters method and causing the rest of the text to be lost.

查看更多
淡お忘
3楼-- · 2019-03-03 04:48

Here's what worked for me with code messing it up commented out. My parsingDes flag was causing only one append.

@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;
        }
    }
查看更多
登录 后发表回答