0

I have been developing an Android RSS Reader Application and have had a problem with fetching HTML content from description node.

I tried to fetch the data from following XML.

        <description>
    <p><a href="http://in.news.yahoo.com/search-arizona-girl-6-turns-back-her-tucson-021230195.html">
   <img src="http://l.yimg.com/bt/api/res/1.2/t8X__zdk6shihpWw0Nenfw--/YXBwaWQ9eW5ld3M7Zmk9ZmlsbDtoPTg2O3B4b2ZmPTUwO3B5b2ZmPTA7cT04NTt3PTEzMA--/http://media.zenfs.com/en_us/News/Reuters/2012-04-24T021230Z_1_CDEE83N064W00_RTROPTP_2_USA-MISSING-ARIZONA.JPG" 
width="130" height="86" alt="Handout photo of Isabel Mercedes Celis" align="left" title="Handout photo of Isabel Mercedes Celis" border="0" />

</a>
      TUCSON, Arizona (Reuters) - The search for a missing 6-year-old Arizona girl who a               authorities said may have been snatched from her bedroom in Tucson entered its third day on  Monday as search dogs shifted investigators' attention back to the child's home. The  parents of first-grader Isabel Mercedes Celis told detectives she was last seen on Friday  night when they tucked her into bed, and was found to have vanished when a family member   entered her room the next morning to awaken her, police said. ...
    </p>
  <br clear="all"/>
 </description>

it display blank when I fetch data. I paste my whole code below..

I am fetching Rss from this url: http://in.news.yahoo.com/rss/crime

RSSActivity.java

package com.satyampv.dsta;


import java.util.ArrayList;
import java.util.HashMap;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;


import android.app.ListActivity;
import android.os.Bundle;

import android.text.util.Linkify;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class AstroRssActivity extends ListActivity {
    /** Called when the activity is first created. */
    //static final String URL = "http://findyourfate.com/rss/dailyhoroscope-feed.asp?sign=Taurus";

    //static final String URL = "http://my.horoscope.com/astrology/daily-horoscopes-rss.html";
    static final String URL = "http://in.news.yahoo.com/rss/crime";
    // XML node keys
    static final String KEY_ITEM = "item"; // parent node
    static final String KEY_TITLE = "title";
    static final String KEY_DESC = "description";
    static final String KEY_LINK = "link";



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

        XMLParser parser = new XMLParser();
        String xml = parser.getXMLFromURL(URL);// getting XML
        Document doc = parser.getDocumentElement(xml);// getting DOM element

        NodeList nl = doc.getElementsByTagName(KEY_ITEM);
        // looping through all item nodes <item>
        for (int i = 0; i < nl.getLength(); i++) {
            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();
            Element e = (Element) nl.item(i);

            // adding each child node to HashMap key => value

            map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
            map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
            map.put(KEY_LINK,parser.getValue(e, KEY_LINK));


            // adding HashList to ArrayList
            menuItems.add(map);
        }

        // Adding menuItems to ListView
        ListAdapter adapter = new SimpleAdapter(this, menuItems,
                R.layout.list_item,
                new String[] { KEY_TITLE, KEY_DESC, KEY_LINK }, new int[] {
                        R.id.name, R.id.desciption, R.id.link });

        setListAdapter(adapter);

XMLParser.java

package com.satyampv.dsta;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


import android.util.Log;

public class XMLParser {


    public XMLParser() {

    }

    public String getXMLFromURL(String url) {

        String xml = null;

        try {
            // Default HTTP Client

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();

            xml = EntityUtils.toString(httpEntity);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // return XML
        return xml;
    }

    // Getting xml Dom element @param xml String

    public Document getDocumentElement(String xml) {

        Document doc = null;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        try {

            DocumentBuilder db = dbf.newDocumentBuilder();

            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xml));
            doc = db.parse(is);
        } catch (ParserConfigurationException e) {
            Log.e("Error", e.getMessage());
            return null;
        } catch (SAXException e) {

            Log.e("Error", e.getMessage());
            return null;

        } catch (IOException e) {
            Log.e("Error", e.getMessage());
            return null;
        }

        return doc;
    }


    public String getValue(Element item,String str){
        NodeList n = item.getElementsByTagName(str);
        return this.getElementValue(n.item(0));
    }
    // Getting node Value
    // @params ele element

    public final String getElementValue(Node elem) {
        Node child;

        if (elem != null) {

            if (elem.hasChildNodes()) {
                for (child = elem.getFirstChild(); child != null; child = child
                        .getNextSibling())
                {
                    if (child.getNodeType() == Node.TEXT_NODE) {
                        return child.getNodeValue();
                    }
                }

            }
        }

        return "";

    }
}
mmcdole
  • 91,488
  • 60
  • 186
  • 222
NovusMobile
  • 1,813
  • 2
  • 21
  • 48

3 Answers3

1

if your description Node contains HTML tags, it does not contain any TEXT_NODE type child, which is why it returns empty.

Check what type are the child nodes in your description Node to see what to do of these.

Edit

One solution is using getTextContent ( http://docs.oracle.com/javase/1.5.0/docs/api/org/w3c/dom/Node.html#getTextContent%28%29 ) instead of searching for a Text node. Instead of:

if (elem.hasChildNodes()) {
    for (child = elem.getFirstChild(); child != null; child = child.getNextSibling()) {
        if (child.getNodeType() == Node.TEXT_NODE) {
            return child.getNodeValue();
        }
    }
}

you can simply go :

return elem.getTextContent();

Later, you can parse the HTML using Html.fromHtml() :

HashMap<String, Spanned> map = new HashMap<String, Spanned>();

and

map.put(KEY_DESC, Html.fromHtml(parser.getValue(e, KEY_DESC)));

(see http://developer.android.com/reference/android/text/Html.html#fromHtml%28java.lang.String%29 )

Edit2

And replace

ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

with

ArrayList<HashMap<String, Spanned>> menuItems = new ArrayList<HashMap<String, Spanned>>();

Moreover, I think SimpleAdapter expects Strings for TextViews, so you may need a ViewBinder to put Spanned in the TextView:

SimpleAdapter adapter = new SimpleAdapter(...);
adapter.setViewBinder(new SimpleAdapter.ViewBinder() {
    public boolean setViewValue(View view, Object data, String textRepresentation) {
        if (data instanceof Spanned && view instanceof TextView) {
            ((TextView) view).setText((Spanned) data));
        }
    }
}
njzk2
  • 38,969
  • 7
  • 69
  • 107
  • yes..I will try.Any example or reference will be appreciable. – NovusMobile Apr 24 '12 at 09:58
  • Actully; here I am using HashMap type String .SO may be due to this In my code I didn't get the Description tag.. whre am I wrong?? Please guide me... – NovusMobile Apr 25 '12 at 12:23
  • In your code, you search for `child.getNodeType() == Node.TEXT_NODE`. There is no such node in Description if description is HTML. There is a `p` node. I'll update my answer to add leads – njzk2 Apr 25 '12 at 13:32
  • Thanks for updating answer but still facing error The method add(HashMap) in the type ArrayList> is not applicable for the arguments (HashMap) hope you are giving my answer . I accept your ans.Tx – NovusMobile Apr 26 '12 at 06:28
  • oh great thanks for editing code . I found that while I am fetching data I found that I didn't receive code which having HTML format. so where is issue? are you gettingme? – NovusMobile Apr 30 '12 at 08:56
0

Check this example.Its a simple RSS reader and very easy to understand... http://droidapp.co.uk/?p=166

Basim Sherif
  • 5,384
  • 7
  • 48
  • 90
0

The best way to display HTML content in android is using Webview.So display the data inside description node using webview.It will display both the text and also images.Here is a sample code...

    WebView Description;
    Description = (WebView)findViewById(R.id.webView1);
    Description.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
    Description.getSettings().setJavaScriptEnabled(true);
    Description.getSettings().setBuiltInZoomControls(true);





    Bundle mybundle = getIntent().getExtras();
    Integer NewsNumber = mybundle.getInt("number");

    final String CurrentTitle = Arrays.Title[NewsNumber];
    String CurrentDescription = Arrays.Description[NewsNumber];


    NewsTitle.setText(CurrentTitle);

    Description.loadDataWithBaseURL (null, "<html>"+CurrentDescription+"</html>", "text/html", "UTF-8",
    null); 
Basim Sherif
  • 5,384
  • 7
  • 48
  • 90
  • Thank you for to help me to give code to display data for html tag. but I struct before that.If you run my code you will find that In tag I didn't get description tex any where . so its duet to HashMap or something else.. – NovusMobile Apr 25 '12 at 12:25
  • k, tell me what you want to achieve? Do you want to list the data from description node? – Basim Sherif Apr 25 '12 at 12:35
  • In my opinion you should list the RSS titles and its images,and when we click on any title the decription data should be displayed in a Webview.This is the way I created an RSS reader, and it works perfectly. – Basim Sherif Apr 25 '12 at 12:41