开发者

Android: Sax parsing to a listview

First off I'm new to Android and Java.. I have been trying to add a "simple" Rss Reader to an app of mine. All I want it to do is Parse a RSS feed from a specific site and take the Title and published date and put those items into a listview and when a list item is clicked it will open the browser to display the webpage containing the article. Easy enough right? I'm sad to say it has had me stumped for a few days now.

I've read a few tutorials/examples and the code that I'm trying to modify to suit my purpose looks like:

Main Activity

public class News extends Activity {

    private final String MY_DEBUG_TAG = "Some NEWS";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
            super.onCreate(icicle);

            /* Create a new TextView to display the parsingresult later. */
            TextView tv = new TextView(this);
            try {
                    /* Create a URL we want to load some xml-data from. */
                    URL url = new URL("http://www.some.com/feed/");

                    /* Get a SAXParser from the SAXPArserFactory. */
                    SAXParserFactory spf = SAXParserFactory.newInstance();
                    SAXParser sp = spf.newSAXParser();

                    /* Get the XMLReader of the SAXParser we created. */
                    XMLReader xr = sp.getXMLReader();
                    /* Create a new ContentHandler and apply it to the XML-Reader*/ 
                    ExampleHandler myExampleHandler = new ExampleHandler();
                    xr.setContentHandler(myExampleHandler);

                    /* Parse the xml-data from our URL. */
                    xr.parse(new InputSource(url.openStream()));
                    /* Parsing has finished. */

                    /* Our ExampleHandler now provides the parsed data to us. */
                    ParsedExampleDataSet 开发者_JAVA百科parsedExampleDataSet = 
                                                                    myExampleHandler.getParsedData();

                    /* Set the result to be displayed in our GUI. */
                    tv.setText(parsedExampleDataSet.toTitle());

            } catch (Exception e) {
                    /* Display any Error to the GUI. */
                    tv.setText("Error: " + e.getMessage());
                    Log.e(MY_DEBUG_TAG, "NewsQueryError", e);
            }
            /* Display the TextView. */
            this.setContentView(tv);
    }
}

ExampleHandler

   public class ExampleHandler extends DefaultHandler{

    // ===========================================================
    // Fields
    // ===========================================================

    private boolean in_entry = false;
    private boolean in_id = false;
    private boolean in_title = false;
    private boolean in_updated = false;
    private boolean in_summary = false;
    private boolean in_link = false;

    private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();




    // ===========================================================
    // Getter & Setter
    // ===========================================================

    public ParsedExampleDataSet getParsedData() {
        return this.myParsedExampleDataSet;
    }

    // ===========================================================
    // Methods
    // ===========================================================
    @Override
    public void startDocument() throws SAXException {
        this.myParsedExampleDataSet = new ParsedExampleDataSet();
    }

    @Override
    public void endDocument() throws SAXException {
            // Nothing to do
    }

    /** Gets be called on opening tags like: 
     * <tag> 
     * Can provide attribute(s), when xml was like:
     * <tag attribute="attributeValue">*/
    @Override
    public void startElement(String namespaceURI, String localName,
                    String qName, Attributes atts) throws SAXException {
            if (localName.equals("entry")) {                    
                    this.in_entry = true;
            }else if (localName.equals("id")) {                 
                    this.in_id = true;
            }else if (localName.equals("title")) {
                    this.in_title = true;
            }else if (localName.equals("updated")){
                    this.in_updated = true;
            }else if (localName.equals("summary")) {
                    this.in_summary = true;
            }else if (localName.equals("link")) {
                    this.in_link = true;
            }
    }

    /** Gets be called on closing tags like: 
     * </tag> */
    @Override
    public void endElement(String namespaceURI, String localName, String qName)
                    throws SAXException {
            if (localName.equals("entry")) {
                    this.in_entry = false;
            }else if (localName.equals("id")) {
                    this.in_id = false;
            }else if (localName.equals("title")) {
                    this.in_title = false;
            }else if (localName.equals("updated")) {
                    this.in_updated = false;
            }else if (localName.equals("summary")) {
                    this.in_summary = false;
            }else if (localName.equals("link")) {
                    this.in_link = false;
            }
    }

    /** Gets be called on the following structure: 
     * <tag>characters</tag> */
    public void characters(char ch[], int start, int length) {
        if(this.in_title){
        myParsedExampleDataSet.setextractedTitle(new String(ch, start, length));
}
}
}

ParsedExampleDataSet

public class ParsedExampleDataSet {
    private String extractedId = null;
    private String extractedTitle = null;
    private String extractedUpdated = null;
    private String extractedSummary = null;
    private String extractedImage = null;
    private int extractedInt = 0;

    public String getextractedId() {
            return extractedId;
    }
    public void setextractedId(String extractedId) {
            this.extractedId = extractedId;
    }

    public String getextractedTitle() {
        return extractedTitle;
    }
    public void setextractedTitle(String extractedTitle) {
        this.extractedTitle = extractedTitle;
    }
    public String getextractedUpdated() {
        return extractedUpdated;
    }
    public void setextractedUpdated(String extractedUpdated) {
        this.extractedUpdated = extractedUpdated;
    }

    public String getextractedSummary() {
        return extractedSummary;
    }
    public void setextractedSummary(String extractedSummary) {
        this.extractedSummary = extractedSummary;
    }



    public String toId(){
            return  this.extractedId;
    }

    public String toTitle(){
        return  this.extractedTitle;
    }

    public String toUpdated(){
        return  this.extractedUpdated;
    }

    public String toSummary(){
        return  this.extractedSummary;
    }
}

Now of course this will just return the last entry in the feed. It is parsing properly as I can get each element that I want to display individually. I'm just clueless as to how to implement a listveiw.

Thanks in advance


Let's take this step by step and hopefully we could achieve what you want to do. I have included relevant links to the API Documentation that you need to know.

  • For ListView, DOM is probably a simpler choice since ListView is operating on a list which would work nicely with structured list. It's also easier to learn for someone who new to Android and Java. Look at this IBM tutorial for XML on section "DOM-based implementation of feed parser". Below is the section of the code you should care for in the example


    DocumentBuilder builder = factory.newDocumentBuilder();
    Document dom = builder.parse(this.getInputStream());
    Element root = dom.getDocumentElement();

  • At this point you have the data for your ListView. ListView works by taking an Adapter. Adapter is the one responsible for a. Setting the initial data and b. Showing how each row should look like. As such this class is important for making ListView works
  • Now you are going to create your own extension of BaseAdapter which will take the root element that you have gotten before. I have provided a skeleton class here:

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class RSSAdapter extends BaseAdapter {
    Element rootElement;

    public RSSAdapter(Element rootElement) {
        this.rootElement = rootElement;
    }

    public int getCount() {
        // get the count of children of the root element
        return 0;
    }

    public Object getItem(int position) {
        // get the child identified by the position, 
        // this is the important part where you    
        // want to get the right child representing the RSS data that you want to get
        return null;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // implement your view here....
        return null;
    }
}

  • If you are not familiar with Element, I suggest you look at the following Element API Documentation. You would need to correctly identify the child in getItem() function above
  • Now you are ready to implement getView() method. Here you would basically do the following step
    • Get access to the child node that you want using getItem() that you have implemented
    • Create an XML layout for each row and inflate them here. If you are not familiar with Android View, look at View API Documentation as this is an important thing to know
    • Extract the data from the child node and set it to your corresponding View element
  • Next, you need to set up OnItemClickListener on your ListView. In the listener you would want to get the XML again using getItem() (this method is crucial for you) and get the link.
  • Finally, in the implementation of onClick(), you want to use WebView and load the URL

This should be enough for you to implement what you want. I would clarify further if the steps are not clear. Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜