SaxParser 无法解析 url
SaxParser is failing to parse url's
我正在尝试使用 SaxParser 解析 xml,但有时无法解析来自 xml 提要的 url。我 xml 喂过这样的东西。
<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);
}
}
}
更新:
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());
}
}
}
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
。
让我们来看看 documentation :
void characters(char[] ch, int start, int length) throws SAXException
The Parser will call this method to report each chunk of character data. SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks
The application must not attempt to read from the array outside of the specified range.
所以上面的代码是非常错误的:
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);
}
我正在尝试使用 SaxParser 解析 xml,但有时无法解析来自 xml 提要的 url。我 xml 喂过这样的东西。
<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);
}
}
}
更新:
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());
}
}
}
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
。
让我们来看看 documentation :
void characters(char[] ch, int start, int length) throws SAXException
The Parser will call this method to report each chunk of character data. SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks
The application must not attempt to read from the array outside of the specified range.
所以上面的代码是非常错误的:
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);
}