2015-01-02 8 views
1

Я пытаюсь разобрать xml с помощью SaxParser, который несколько раз не анализирует URL-адрес, который поступает в XML-канал. Я использую xml для чего-то вроде этого.SaxParser не удается разобрать url

<songs> 
    <song id="269611"> 
    <start>2015-01-02T04:36:52Z</start> 
    <title>Beyond Me</title> 
    <artist>tobyMac</artist> 
    <logo>http://www.quuit.com/quu/content/themes/base/images/music_none.png</logo> 
    <lyrics>no</lyrics> 
    <bio>yes</bio> 
    <coupon>no</coupon> 
    <ad>no</ad> 
    </song> 
    <song id="77476"> 
    <start>2015-01-2T04:32:51Z</start> 
    <title>WHOLLY YOURS</title> 
    <artist>David Crowder Band</artist> 
    <logo>http://www.quuit.com/imageserver/thumbnail/WHOLLY_YOURSDavid_Crowder_Band.jpeg</logo> 
    <lyrics>no</lyrics> 
    <bio>yes</bio> 
    <coupon>no</coupon> 
    <ad>no</ad> 
    </song> 
</songs> 

Когда я пытаюсь разобрать выше, несколько раз URL-адрес в логотипе тега становится усечен. Вместо http://www.quuit.com/imageserver/thumbnail/WHOLLY_YOURSDavid_Crowder_Band.jpeg этот url, я просто получаю Band.jpeg или wder_Band.jpeg и т. Д., И иногда он дает полный URL-адрес, который в порядке. Эта проблема происходит случайным образом и выглядит странно. Кто-то мне помогает в этом.

вот код, который я написал для разбора выше XML:

public class QuuAsyncTask extends AsyncTask<Object, Void, BaseQuuVO> { 

private Exception exception; 
private QuuServiceDelegate serviceDelegate; 

protected BaseQuuVO doInBackground(Object... param) { 
    BaseQuuVO baseVO = new BaseQuuVO(); 

    try { 
     QuuDefaultHandler defaultHandler = (QuuDefaultHandler) param[1]; 
     serviceDelegate = (QuuServiceDelegate) param[2]; 
     /** Handling XML */ 
     SAXParserFactory spf = SAXParserFactory.newInstance(); 
     SAXParser sp = spf.newSAXParser(); 
     XMLReader xr = sp.getXMLReader(); 

     /** Send URL to parse XML Tags */ 
     URL sourceUrl = new URL((String) param[0]); 

     /** Create handler to handle XML Tags (extends DefaultHandler) */ 
     xr.setContentHandler(defaultHandler); 
     InputSource inputSource = new InputSource(sourceUrl.openStream()); 
     inputSource.setEncoding("ISO-8859-1"); 
     xr.parse(inputSource); 
     baseVO = (BaseQuuVO) defaultHandler.getData(); 
     return baseVO; 
    } catch (Exception e) { 
     this.exception = e; 
     return null; 
    } 
} 

protected void onPostExecute(BaseQuuVO result) { 
    super.onPostExecute(result); 
    // TODO: check this.exception 
    // TODO: do something with the feed 
    if (result != null) { 
     serviceDelegate.quuResponseReceived(result); 
    } else { 
     serviceDelegate.quuResponseFailure("Problem loading data"); 
    } 

} 

public class QuuAsyncTask extends AsyncTask<Object, Void, BaseQuuVO> { 

    private Exception exception; 
    private QuuServiceDelegate serviceDelegate; 

    protected BaseQuuVO doInBackground(Object... param) { 
     BaseQuuVO baseVO = new BaseQuuVO(); 

     try { 
      QuuDefaultHandler defaultHandler = (QuuDefaultHandler) param[1]; 
      serviceDelegate = (QuuServiceDelegate) param[2]; 
      /** Handling XML */ 
      SAXParserFactory spf = SAXParserFactory.newInstance(); 
      SAXParser sp = spf.newSAXParser(); 
      XMLReader xr = sp.getXMLReader(); 

      /** Send URL to parse XML Tags */ 
      URL sourceUrl = new URL((String) param[0]); 

      /** Create handler to handle XML Tags (extends DefaultHandler) */ 
      xr.setContentHandler(defaultHandler); 
      InputSource inputSource = new InputSource(sourceUrl.openStream()); 
      inputSource.setEncoding("ISO-8859-1"); 
      xr.parse(inputSource); 
      baseVO = (BaseQuuVO) defaultHandler.getData(); 
      return baseVO; 
     } catch (Exception e) { 
      this.exception = e; 
      return null; 
     } 
    } 

    protected void onPostExecute(BaseQuuVO result) { 
     super.onPostExecute(result); 
     // TODO: check this.exception 
     // TODO: do something with the feed 
     if (result != null) { 
      serviceDelegate.quuResponseReceived(result); 
     } else { 
      serviceDelegate.quuResponseFailure("Problem loading data"); 
     } 

    } 
} 

public class PlayListXMLParser extends QuuDefaultHandler { 

    private List<PlayListSongVO> songsVO; 
    private String tempVal; 
    private PlayListSongVO tempPlayListSongVO; 
    private PlayListsVO playListsVO = new PlayListsVO(); 

    public PlayListXMLParser() { 
     songsVO = new ArrayList<PlayListSongVO>(); 
    } 

    @Override 
    public PlayListsVO getData() { 
     playListsVO.setSongs(songsVO); 
     return playListsVO; 
    } 

    // Event Handlers 
    public void startElement(String uri, String localName, String qName, 
          Attributes attributes) throws SAXException { 
     // reset 
     tempVal = ""; 
     if (qName.equalsIgnoreCase("song")) { 
      // create a new instance of employee 
      tempPlayListSongVO = new PlayListSongVO(); 
     } 
    } 

    public void characters(char[] ch, int start, int length) 
      throws SAXException { 
     tempVal = new String(ch, start, length); 
    } 

    public void endElement(String uri, String localName, String qName) 
      throws SAXException { 
     if (qName.equalsIgnoreCase("song")) { 
      // add it to the list 
      songsVO.add(tempPlayListSongVO); 
     } else if (qName.equalsIgnoreCase("id")) { 
      tempPlayListSongVO.setId(tempVal); 
     } else if (qName.equalsIgnoreCase("start")) { 
      tempPlayListSongVO.setStart(tempVal); 
     } else if (qName.equalsIgnoreCase("title")) { 
      tempPlayListSongVO.setTitle(tempVal); 
     } else if (qName.equalsIgnoreCase("artist")) { 
      tempPlayListSongVO.setArtist(tempVal); 
     } else if (qName.equalsIgnoreCase("logo")) { 
      tempPlayListSongVO.setLogo(tempVal); 
     } else if (qName.equalsIgnoreCase("lyrics")) { 
      tempPlayListSongVO.setLyrics(tempVal); 
     } else if (qName.equalsIgnoreCase("bio")) { 
      tempPlayListSongVO.setBio(tempVal); 
     } else if (qName.equalsIgnoreCase("coupon")) { 
      tempPlayListSongVO.setCoupon(tempVal); 
     } else if (qName.equalsIgnoreCase("ad")) { 
      tempPlayListSongVO.setAd(tempVal); 
     } 

    } 
} 

Update:

public class SongDetailXMLParser extends QuuDefaultHandler { 

    // private String tempVal; 
    private SongDetailsVO songDetailsVO; 
    private StringBuilder tempStringBuilder; 

    public SongDetailXMLParser() { 

    } 

    @Override 
    public SongDetailsVO getData() { 
     return songDetailsVO; 
    } 

    // Event Handlers 
    public void startElement(String uri, String localName, String qName, 
          Attributes attributes) throws SAXException { 
     tempStringBuilder = new StringBuilder(); 
     if (qName.equalsIgnoreCase("song")) { 
      // create a new instance 
      songDetailsVO = new SongDetailsVO(); 
     } 
    } 

    public void characters(char[] ch, int start, int length) 
      throws SAXException { 
     tempStringBuilder.append(ch); 

    } 

    public void endElement(String uri, String localName, String qName) 
      throws SAXException { 
     if (qName.equalsIgnoreCase("song")) { 
      // add it to the list 

     } else if (qName.equalsIgnoreCase("id")) { 
      songDetailsVO.setId(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("duration")) { 
      songDetailsVO.setDuration(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("title")) { 
      songDetailsVO.setTitle(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("artist")) { 
      songDetailsVO.setArtist(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("logo")) { 
      songDetailsVO.setLogo(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("amazon")) { 
      songDetailsVO.setAmazon(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("itunes")) { 
      songDetailsVO.setItunes(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("videolink")) { 
      songDetailsVO.setVideolink(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("ringtone")) { 
      songDetailsVO.setRingtone(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("lyrics")) { 
      songDetailsVO.setLyrics(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("bio")) { 
      songDetailsVO.setBio(tempStringBuilder.toString()); 
     } else if (qName.equalsIgnoreCase("share")) { 
      songDetailsVO.setShare(tempStringBuilder.toString()); 
     } 
    } 
} 
+2

Взгляните на [это] (http://stackoverflow.com/questions/4567636/java-sax-pars er-split-calls-to-characters) Вопрос. Я думаю, что это та же проблема.В принципе, вам нужно аккумулировать данные, данные методу 'characters'. – Diego

ответ

3

Давайте посмотрим на documentation:

void characters(char[] ch, int start, int length) throws SAXException

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

Приложение должно не попытка чтения из массива за пределами указанного диапазона.

Так что приведенный выше код очень неправильно:

public void characters(char[] ch, int start, int length) 
     throws SAXException { 
    tempStringBuilder.append(ch); 
} 

Так это один, как вы воссоздать String для каждой порции:

public void characters(char[] ch, int start, int length) 
     throws SAXException { 
    tempVal = new String(ch, start, length); 
} 

Попробуйте это:

public void characters(char[] ch, int start, int length) 
     throws SAXException { 
    tempStringBuilder.append(ch, start, length); 
} 
+0

Спасибо ... Это работает !!! :) – Ramesh

2

XML, синтаксическому анализатору разрешено разбивать текстовые узлы любым способом, который им нравится, и предоставлять их в нескольких вызовах метода characters(). Ваш метод characters() не учитывает это:

public void characters(char[] ch, int start, int length) 
     throws SAXException { 
    tempVal = new String(ch, start, length); 
} 

Если это называется более чем один раз, tempVal будет просто содержать результат последнего вызова.

Чтобы собрать всю текстовую информацию, вы можете использовать следующее:

public void characters(char[] ch, int start, int length) 
    throws SAXException { 
    tempStringBuilder.append(ch, start, length); 

} 

если вы определили переменную tempStringBuilder как StringBuilder или StringBuffer в другом месте.

+0

Привет Майкл, Спасибо за предложение, я попытался использовать StringBuilder вместо строки. Но результат тот же, строка усекается. Можете ли вы помочь мне в этом ... Спасибо. – Ramesh

+0

Я могу помочь вам найти ошибки в вашем коде, если вы покажете мне свой код, но я не могу, если вы этого не сделаете. –

+0

Привет @ Майкл, я добавил код выше. Пожалуйста, взгляните на это. Заранее спасибо. – Ramesh

Смежные вопросы