SaxParser未能解析网址

时间:2015-01-02 12:54:44

标签: java android xml saxparser xmlpullparser

我试图使用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());
        }
    }
}

1 个答案:

答案 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);
}