1

I'm using android's SAX parser and I wish to stop processing after I have read N elements. Some of the feeds are quite large and can take a while to churn through. How can I stop parsing if certain conditions are met in the EndElementListener for a certain element? Here is my current listener

chanItem.setEndElementListener(new EndElementListener()  {
    public void end() {
        _items.add(_item);
        if (++_currentItem == _maxElements) {
                //BREAK OUT HERE
        }
    }
});

I've tried throwing an exception within end() but EndElementListener doesn't allow for throwing any exceptions. Guidance would be much appreciated.

Fergal Moran
  • 4,525
  • 5
  • 39
  • 54
  • Duplicate of http://stackoverflow.com/q/1345293/965648 – Nick Garvey Nov 30 '11 at 19:49
  • It's actually not Nick - if you have a look you'll see that mine is a bit different because it's using the android.sax parser. I can't throw an exception within the EndElementListener because the interface doesn't support it. – Fergal Moran Nov 30 '11 at 19:59
  • It appears that it does, I am looking at: http://developer.android.com/reference/javax/xml/parsers/SAXParser.html – Nick Garvey Nov 30 '11 at 20:01
  • Ah my mistake, I wasn't looking at the proper one. I'm not sure then, sorry for the confusion. This was discussed on a different question, although no answer is marked. http://stackoverflow.com/q/3508635/965648 – Nick Garvey Nov 30 '11 at 20:04
  • It's terrible confusing Nick, don't worry about it at all... I just much rather the way the android.sax parser does it with the ElementListeners so I'd like to continue to use it, assuming I can get this working.. – Fergal Moran Nov 30 '11 at 20:08

2 Answers2

2

Define a new unchecked exception called "SaxBreakOutException":

class SaxBreakOutException extends RuntimeException {
}

Throw this in your listener:

chanItem.setEndElementListener(new EndElementListener()  {
    public void end() {
        _items.add(_item);
        if (++_currentItem == _maxElements) {
            throw new SaxBreakOutException();
        }
    }
});

And catch it in the code that calls XmLReader.parse():

reader.setContentHandler(handler);
try {
    reader.parse(new InputSource(new StringReader(xml)));
} catch (SaxBreakOutException allDone) {
}

Alternatively, switch to Android's XmlPullParser which doesn't require exceptions to break out early.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
  • Fantastic! I was trying this method myself but was extending SaxException instead of RuntimeException. Thanks Jesse.. – Fergal Moran Dec 21 '11 at 22:09
0

The Answer of "Jesse Wilson" is good but in my case I had to preserve de values that returns my parse() method.

List<Article> ArticleNews = parser.parse();

So i added a boolean value;

int countArts;
boolean stopParse;

when i had to stop my parser() method, i consume all the listeners with

if(stopParse)return;

an example:

public List<Article> parse(){
        final List<Article> myArticles= new ArrayList<Article>();

        final RootElement root = new RootElement("articles");
        Element nota = root.getChild("article");


        nota.setStartElementListener(new StartElementListener(){
            @Override
            public void start(Attributes attributes) {
                Log.i("----------------------------------------", "START Article!\n");
            }
        });

        nota.setEndElementListener(new EndElementListener(){
            public void end() {  

                if(countArts>9){    //only 10 articles!.
                    stopParse=true;
                }               
                countArts++;
                Log.i("----------------------------------------", "END Article!\n");

            }
        });


        nota.getChild(ID).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                if(stopParse)return;
                if(Utilities.isNumeric(body)) {
                    idA = body;
                }
            }
        });
        nota.getChild(CATEGORY).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                if(stopParse)return;
                categoriaA = body;
            }
        });

        nota.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                if(stopParse)return;
                tituloA = body;
            }
        });

        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
        }  catch (Exception e) {
            Log.e(" *** Exception Xml.parse() ", e.getMessag
        }
        return myArticles;
    }
Jorgesys
  • 124,308
  • 23
  • 334
  • 268