Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to implement few different types of parsers that is one which will store data in sqllite database or one which just fetches and displays the rss feed data. At the moment I am working on the latter one and I have implemented quite a few(using XMLPullParser or SAX) from various tutorials however there is always something wrong with them.

I will list a code(modified to suit my needs), which worked just fine(before modifications) when I connected to xml data link from the tutorial , however it doesn't work with the rss data link i need data from even though I changed the tag names accordingly. Application launches and returns just the last node, with some html tags and incomplete. I have found other rss feed , which has much less information and so I'm fine using it instead, however it has 1 extra tag attribute and I'm not sure how to modify my code to work with it.

As you can see the xml data link from tutorial has a quite simple structure as in parent posts node going to post child nodes and those child nodes having all the tags with data. However in the case of the rss feeds I need data from they start off with rss->channel->item->data or rss->channel->language en->item->data. How do I modify my code so that I can go all the way to the data? Return all of nodes, not just last one and full contents of the node.


   package com.example.travelparser;

   import android.app.Activity;
   import android.app.ProgressDialog;
   import android.os.AsyncTask;
   import android.os.Bundle;
   import android.widget.TextView;

public class MainActivity extends Activity {

TextView tvResponse;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tvResponse = (TextView) findViewById(R.id.tvResponse);
    new PostAsync().execute();
}

class PostAsync extends AsyncTask<Void, Void, Void> {
    ProgressDialog pd;
    XMLHelper helper;


    @Override
    protected void onPreExecute() {
        pd = ProgressDialog.show(MainActivity.this, "Travel Warnings", "Loading posts for Travel Warnings ...", true, false);
    }
    @Override
    protected Void doInBackground(Void... arg0) {
        helper = new XMLHelper();
        helper.get();
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        StringBuilder builder = new StringBuilder();
        for(PostValue item : helper.rss) {
            builder.append("\nTitle: " + item.getTitle());
            builder.append("\nPublish Date: " + item.getDate());
            builder.append("\nLink: " + item.getLink());
            builder.append("\nGuid: " + item.getGuid());
            builder.append("\nDescription: " + item.getDescription());
            builder.append("\n");
        }
        tvResponse.setText(builder.toString());
        pd.dismiss();
    }

}

}

package com.example.travelparser;

/**
 * A class for getters and setters for post
 * */
 public class PostValue {
String title, guid, date, link, description;

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getGuid() {
    return guid;
}

public void setGuid(String guid) {
    this.guid = guid;
}

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}
public String getLink() {
    return link;
}

public void setLink(String link) {
    this.link = link;
}
public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}
  }

package com.example.travelparser;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

public class XMLHelper extends DefaultHandler {
/** 
 * The URL to be parsed
 */
private String URL_MAIN = "http://travel.state.gov/_res/rss/TWs.xml";
String TAG = "XMLHelper";

Boolean currTag = false;
String currTagVal = "";
public PostValue channel = null;
public ArrayList<PostValue> rss = new ArrayList<PostValue>();

/**
 * Method to read XML from {@link XMLHelper#URL_MAIN}
 * */
public void get() {
    try {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser mSaxParser = factory.newSAXParser();
        XMLReader mXmlReader = mSaxParser.getXMLReader();
        mXmlReader.setContentHandler(this);
        InputStream mInputStream = new URL(URL_MAIN).openStream();
        mXmlReader.parse(new InputSource(mInputStream));
    } catch(Exception e) {
        // Exceptions can be handled for different types
        // But, this is about XML Parsing not about Exception Handling
        Log.e(TAG, "Exception: " + e.getMessage());
    }
}

// This method receives notification character data inside an element
// e.g. <item_title>Add EditText Programmatically - Android</item_title>
// It will be called to read "Add EditText Programmatically - Android"
@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    if(currTag) {
        currTagVal = currTagVal + new String(ch, start, length);
        currTag = false;
    }
}

// Receives notification of end of element
// e.g. <item_title>Add EditText Programmatically - Android</item_title>
// It will be called when </item_title> is encountered
@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    currTag = false;

    if(localName.equalsIgnoreCase("title"))
        channel.setTitle(currTagVal);

    else if(localName.equalsIgnoreCase("pubDate"))
        channel.setDate(currTagVal);

    else if(localName.equalsIgnoreCase("link"))
        channel.setLink(currTagVal);

    else if(localName.equalsIgnoreCase("guid"))
        channel.setGuid(currTagVal);

    else if(localName.equalsIgnoreCase("description"))
        channel.setDescription(currTagVal);

    else if(localName.equalsIgnoreCase("channel"))
        rss.add(channel);
}

// Receives notification of start of an element
// e.g. <item_title>Add EditText Programmatically - Android</item_title>
// It will be called when <item_title> is encountered
@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    Log.i(TAG, "TAG: " + localName);

    currTag = true;
    currTagVal = "";
    // Whenever <item> element is encountered it will create new object of PostValue
    if(localName.equals("channel"))
        channel = new PostValue();
}
}

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
    android:id="@+id/tvResponse"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

</ScrollView>

Thanks in advance guys.

EDIT: I have written new version of this parser for the 2nd link and it returns the last node from the feed as well.

share|improve this question

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.