2015-08-28 1 views
1

Я пытаюсь использовать анализатор SAX, чтобы возвращать содержимое RSS-канала из URL-адреса - http://pitchfork.com/rss/news/, но часто символы теряются при отображении заголовка, показывая частичный текст или только закрывающий тег ">"RSS Reader с использованием Sax Parser потерять символы из заголовка

Как я могу изменить класс обработчика, чтобы предотвратить это? Я думаю, что я, вероятно, должен использовать StringBuilder или StringBuffer, но я не уверен, как его реализовать.

ParseHandler.java

public class RssParseHandler extends DefaultHandler { 
//Parsed items 
private List<RssItem> rssItems; 
private RssItem currentItem; 
private boolean parsingTitle; 
private boolean parsingLink; 
private boolean parsing_id; 
private boolean parsingDescription; 

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

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

//Creates empty RssItem object during the process of an item start tag 
//Indicators are set to true when particular tag is being processed 
@Override 
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 

    if ("item".equals(qName)) { 
     currentItem = new RssItem(); 

    } else if ("title".equals(qName)) { 
     parsingTitle = true; 


    } else if ("link".equals(qName)) { 
     parsingLink = true; 


    } else if ("_id".equals(qName)) { 
     parsing_id = true; 


    } else if ("description".equals(qName)) { 
     parsingDescription = true; 

    } 
} 

//Current RssItem is added to the list following process of end tag 
@Override 
public void endElement(String uri, String localName, String qName) throws SAXException { 

    if ("item".equals(qName)) { 
     rssItems.add(currentItem); 
     currentItem = null; 

    } else if ("title".equals(qName)) { 
     parsingTitle = false; 

    } else if ("link".equals(qName)) { 
     parsingLink = false; 

    } else if ("_id".equals(qName)) { 
     parsing_id = false; 

    } else if ("description".equals(qName)) { 
     parsingDescription = 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 (parsingLink) { 
     if (currentItem != null) { 
      currentItem.setLink(new String(ch, start, length)); 
      parsingLink = false; 
     } 

    } else if (parsing_id) { 
     if (currentItem != null) { 
      currentItem.set_id(new String(ch, start, length)); 
      parsing_id = false; 
     } 

    } else if (parsingDescription) { 
     if (currentItem != null) { 
      currentItem.setDescription(new String(ch, start, length)); 
      parsingDescription = false; 
     } 

    } 
}}//rssHandlerClass 

ответ

0

Используйте StringBuilder для создания тега, а не использовать новый экземпляр String, в качестве документации говорит:

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

И @CommonWares говорит, что это именно на своем посту Here.

Создайте свой тег как его найти, используя StringBuilder, так как есть куски, поступающие на один раз, а не всю строке (Это объясняет неполные тег!). Вы можете или не нуждаетесь в флаге isBuilding, но я не знаю всей вашей реализации, поэтому я добавил его incase.

StringBuilder mSb; 
    boolean isBuilding; 

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

     mSb = new StringBuilder(); 
     isBuilding = true; 

     if(qName.equals("title")){ 
      parsingTitle = true; 
     } 
     ... 
     ... 
    } 

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

    @Override 
    public void endElement(String uri, String localName, String qName) 
     throws SAXException { 

     if(parsingTitle){ 
      currentItem.setTitle(sb.toString().trim()); 
      parsingTitle = false; 
      isBuilding = false; 
     } 
    } 
+0

Отличный ответ, спасибо! –