我试图使用SaxParser解析xml,有时候无法解析xml feed中的url&#39。我有点像这样的东西。
<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>
当我尝试解析上述内容时,有时徽标标记中的网址会被截断。而不是http://www.quuit.com/imageserver/thumbnail/WHOLLY_YOURSDavid_Crowder_Band.jpeg这个网址,我只是得到了Band.jpeg或者wder_Band.jpeg等,有时它会提供完整的网址,这很好。这个问题随机发生,看起来很奇怪。有人请帮助我。
这是我用来解析上面的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);
}
}
}
更新:
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());
}
}
}
答案 0 :(得分:4)
让我们来看看documentation:
void characters(char[] ch, int start, int length) throws SAXException
Parser将调用此方法来报告每个字符数据块。 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);
}