Парсер Android SAX не получает полный текст между тегами - PullRequest
20 голосов
/ 15 мая 2010

Я создал свой собственный DefaultHandler для анализа RSS-каналов, и для большинства каналов он работает нормально, однако для ESPN он обрезает часть URL-адреса статьи из-за того, как ESPN форматирует его URL-адреса. Пример полного URL статьи из ESPN ..

http://sports.espn.go.com/nba/news/story?id=5189101&campaign=rss&source=ESPNHeadlines

По какой-то причине метод символов DefaultHandler получает это только из тега, содержащего вышеуказанный URL.

http://sports.espn.go.com/nba/news/story?id=5189101

Как вы можете видеть, он удаляет все URL из кода амперсанда и escape-кода и после него. Как я могу заставить синтаксический анализатор SAX не обрезать мою строку в этом escape-коде? Для исх. вот мой метод персонажей ..

 public void characters(char ch[], int start, int length) {

  String chars = (new String(ch).substring(start, start + length));

  try {
   // If not in item, then title/link refers to feed
   if (!inItem) {
    if (inTitle)
     currentFeed.title = chars;
   } else {
    if (inLink)
     currentArticle.url = new URL(chars);
    if (inTitle)
     currentArticle.title = chars;
    if (inDescription)
     currentArticle.description = chars;
    if (inPubDate)
     currentArticle.pubDate = chars;
    if (inEnclosure) {
    }
   }
  } catch (MalformedURLException e) {
   Log.e("RSSReader", e.toString());
  }
 }

Роб У.

Ответы [ 2 ]

46 голосов
/ 15 мая 2010

Как видите, это резка все от URL от код выхода после амперсанда и после.

Из документации метода characters():

Парсер вызовет этот метод для сообщать каждый кусок символьных данных. SAX парсеры могут вернуть все смежные символьные данные в одном блоке, или они могут разделить его на несколько частей; Тем не менее, все персонажи в любом одно событие должно происходить из того же внешняя сущность, так что локатор предоставляет полезную информацию.

Когда я пишу парсеры SAX, я использую StringBuilder, чтобы добавить все, что передано characters():

public void characters (char ch[], int start, int length) {
    if (buf!=null) {
        for (int i=start; i<start+length; i++) {
            buf.append(ch[i]);
        }
    }
}

Затем в endElement() я беру содержимое StringBuilder и что-то с ним делаю. Таким образом, если парсер несколько раз звонит characters(), я ничего не пропускаю.

6 голосов
/ 29 мая 2012
@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    // TODO Auto-generated method stub
    sb=new StringBuilder();
    if(localName.equals("icon"))
    {
        iconflag=true;
    }
}

@Override
public void characters (char ch[], int start, int length) {
    if (sb!=null && iconflag == true) {
        for (int i=start; i<start+length; i++) {
            sb.append(ch[i]);
        }
    }
}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    // TODO Auto-generated method stub
    if(iconflag)
    {
        info.setIcon(sb.toString().trim());
        iconflag=false;
    }
}

Итак, я понял, код выше - это решение.

...