Ограничьте XML SAXParser определенным числом или элементом

Я разбираю RSS-ленту новостей XML для приложения Android. Я использую SAXParser, и все работает должным образом, но я хотел бы иметь возможность ограничить количество получаемых историй, и я не могу найти способ сделать это. Например, предположим, что есть 45 историй из одной из новостных лент, и мне просто нужны самые новые 10. Сейчас я просто собираю их все в ArrayList и отображаю только те, которые мне нужны, что, безусловно, является самым большим. Я уверен, что это эффективный способ сделать это.

При необходимости могу предоставить код синтаксического анализа.

Спасибо всем, кто смотрит на это!


person WeVie    schedule 28.09.2014    source источник
comment
Когда вы добавляете объекты в Arraylist, просто проверяйте его размер и не добавляйте к нему, если в нем 10 элементов.   -  person Misagh Emamverdi    schedule 28.09.2014
comment
Я думал об этом, но это означало бы, что весь XML все равно будет анализироваться. Я бы предпочел просто прекратить синтаксический анализ, как только ArrayList достигнет желаемого размера.   -  person WeVie    schedule 28.09.2014
comment
Вы можете просто прервать / вернуться из операции синтаксического анализа после достижения желаемого количества элементов (или до тех пор, пока не останется больше для обработки, в зависимости от того, что наступит раньше)?   -  person MH.    schedule 28.09.2014
comment
Как так @MH. ? Будет ли работать простой break, если я добавлю счетчик к методу startElement(), в котором я добавляю объекты в список?   -  person WeVie    schedule 28.09.2014
comment
Извините, этот комментарий был немного неточным: перерыв или возврат не сработают. Вам придется создать исключение, как это предлагается здесь. Быстрый поиск по SO дает тот же ответ. Не самый красивый, но функциональный, я полагаю ... Взгляните на принятый ответ здесь для некоторых конкретных указателей.   -  person MH.    schedule 28.09.2014


Ответы (2)


Вы можете остановить синтаксический анализатор SAX от дальнейшего синтаксического анализа входных данных, если любой из ваших методов обратного вызова (например, startElement) генерирует исключение SAXException.

Вам нужно будет сделать это исключение распознаваемым (например, используя специальный текст сообщения или используя подкласс SAXException), чтобы, когда ваш исходный вызов parse () вернулся с исключением, вы могли отличить его от других причин сбоя парсера. .

person Michael Kay    schedule 28.09.2014
comment
У вас есть пример, как это сделать? - person WeVie; 28.09.2014
comment
Боюсь, не простой. Пример общей техники можно найти в grepcode.com/file/repo1.maven.org/maven2/net.sourceforge.saxon/, но он не использует интерфейсы SAX напрямую, поэтому события и исключения немного отличаются. (В этом примере нужно прочитать инструкцию обработки xml-таблицы стилей в начале файла, а затем прервать синтаксический анализ при обнаружении первого узла элемента.) - person Michael Kay; 29.09.2014

Я не уверен, что есть способ остановить синтаксический анализ sax. Однако вместо этого вы можете использовать XMLPullParser.

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(yourXML);

int eventType = xpp.getEventType();

while (eventType != XmlPullParser.END_DOCUMENT && list.size() <= MAX_SIZE) {

    if (eventType == XmlPullParser.START_TAG) {
        //do something
    } else if (eventType == XmlPullParser.END_TAG) {
        //do something
    } else if (eventType == XmlPullParser.TEXT) {
        //do something
    }
    eventType = xpp.next();
}

Вы можете найти множество примеров, выполнив поиск по руководству XMLPullParser.

Примечание. Я думаю, что если у вас всего 45 элементов, синтаксический анализ будет очень быстрым, и вы можете позволить sax продолжить синтаксический анализ.

Обновление: я думаю, что это то, что говорит Майкл:

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

   if(size == MAX_SIZE){
      throw new SAXException("end");
    }
    //...
 }

И когда вы разбираете:

try{
saxParser.parse(yourXML);
}catch(SAXException e){
  if(e.getMessage().equals("end"){
    // document has ended
  }
}
person Misagh Emamverdi    schedule 28.09.2014
comment
Я просто использовал 45 в качестве примера. А если их сотни? Это уже не так быстро. Я знаю о PullParser, но мне нужно больше узнать о SAX. - person WeVie; 28.09.2014