0

I'm making an android app where I want to show a random quote of the day with their author to users. For this I'm using the Quote API from They said so. I'm trying to parse this http://api.theysaidso.com/qod.xml file so I can use the quote of the day with their author in my code. But for some reason the result parameter in my onPostExecute is empty. So I guess the XML isn't properly parsed or I don't put the right values in my ArrayList that is a result of the xmlParser.parse(inputStream) method? Or what could be the cause of my ArrayList result still being empty?

XML PARSER:

public class XMLParser {

private static final String ns = null;


public List parse(InputStream in) throws XmlPullParserException, IOException {
    try {
        XmlPullParser parser = Xml.newPullParser();
        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
        parser.setInput(in, null);
        parser.nextTag();
        return readResponse(parser);
    } finally {
        in.close();
    }
}

private List readResponse(XmlPullParser parser) throws XmlPullParserException, IOException {
    List quotes = new ArrayList();

    parser.require(XmlPullParser.START_TAG, ns, "response");
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        // Starts by looking for the entry tag
        if (name.equals("quotes")) {
            quotes.add(readEntry(parser));
        } else {
            skip(parser);
        }
    }
    return quotes;
}

public static class Quote{
    public final String quote;
    public final String author;

    private Quote(String quote, String author) {
            this.quote = quote;
            this.author = author;
    }

}

// Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them off
// to their respective "read" methods for processing. Otherwise, skips the tag.
private Quote readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "quotes");
    String quote = null;
    String author = null;

    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("quote")) {
            quote = readQuote(parser);
        } else if (name.equals("author")) {
            author = readAuthor(parser);
        } else {
            skip(parser);
        }
    }
    return new Quote(quote, author);
}

// Processes quote tags in the feed.
private String readQuote(XmlPullParser parser) throws IOException, XmlPullParserException {
    parser.require(XmlPullParser.START_TAG, ns, "quote");
    String quote = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, "quote");
    return quote;
}

// Processes author tags in the feed.
private String readAuthor(XmlPullParser parser) throws IOException, XmlPullParserException {
    parser.require(XmlPullParser.START_TAG, ns, "author");
    String author = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, "author");
    return author;
}

// For the tags quote and author, extracts their text values.
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
    String result = "";
    if (parser.next() == XmlPullParser.TEXT) {
        result = parser.getText();
        parser.nextTag();
    }
    return result;
}

private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
    if (parser.getEventType() != XmlPullParser.START_TAG) {
        throw new IllegalStateException();
    }
    int depth = 1;
    while (depth != 0) {
        switch (parser.next()) {
            case XmlPullParser.END_TAG:
                depth--;
                break;
            case XmlPullParser.START_TAG:
                depth++;
                break;
        }
    }
}

}

MY ACTIVITY

String url="http://api.theysaidso.com/qod.xml";
    setContentView(R.layout.activity_quotes);
    new DownloadXML().execute(url);

private class DownloadXML extends AsyncTask<String,Void,ArrayList> {

    @Override
    protected ArrayList doInBackground(String... url) {

        ArrayList lijstQuote = new ArrayList();


        try {
            InputStream inputStream = new URL(url[0]).openStream();

            XMLParser xmlParser = new XMLParser();
            lijstQuote =(ArrayList) xmlParser.parse(inputStream);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return lijstQuote;
    }

    protected void onPostExecute(ArrayList result) {

        if (!result.isEmpty()) {
            XMLParser.Quote contents = (XMLParser.Quote) result.get(0);
            TextView quoteTekst = (TextView) findViewById(R.id.quote);
            quoteTekst.setText(contents.quote);

            TextView authorTekst = (TextView) findViewById(R.id.author);
            authorTekst.setText(contents.author);
        }
        else
        {
            TextView quoteTekst = (TextView) findViewById(R.id.quote);
            quoteTekst.setText(R.string.outOfQuotes);

            TextView authorTekst = (TextView) findViewById(R.id.author);
            authorTekst.setText(R.string.authorOutOfQuotes);
        }
    }
}
MrSpokes
  • 37
  • 1
  • 7

1 Answers1

0

Very simple. Use XML Linq

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
                "<?xml version=\"1.0\"?>" +
                    "<response>" +
                      "<success>" +
                        "<total>1</total>" +
                      "</success>-<contents>" +
                        "<quotes>" +
                          "<quote>I quote others only to better express myself. </quote>" +
                          "<length>46</length>" +
                          "<author>Michel de Montaigne</author>" +
                          "<tags>humor</tags>" +
                          "<tags>irony</tags>" +
                          "<tags>truth</tags>" +
                          "<tags>tso-funny</tags>" +
                          "<category>funny</category>" +
                          "<id>dfSt40pVwYqH6_y1K_A7iAeF</id>" +
                        "</quotes>" +
                      "</contents>" +
                    "</response>";

            XDocument doc = XDocument.Parse(input);

            var results = doc.Descendants("quotes").Select(x => new
            {
                quote = (string)x.Element("quote"),
                author = (string)x.Element("author")
            }).ToList();
        }
    }
}
​
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • this topic was useful for me too: http://stackoverflow.com/questions/8897459/parsing-xml-from-website-to-an-android-device – MrSpokes Aug 15 '15 at 14:08
  • You can parse XML using either XmlDocument (like in the posting) or with XDocument (xml linq). The xml linq code requires less code and is easy to do most type of parsing. You can get the same results using either method. – jdweng Aug 15 '15 at 14:11
  • If you are getting multiple quotes in each response you may need to change from : Descendants("quotes") to : Descendants("quote") – jdweng Aug 15 '15 at 14:19