从Android RSS阅读器中的描述节点问题中获取数据

时间:2012-04-24 08:35:52

标签: android xml-parsing rss-reader android-parser

我一直在开发Android RSS阅读器应用程序,并且从描述节点获取HTML内容时遇到了问题。

我尝试从以下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>

我获取数据时显示空白。 我在下面粘贴了整个代码..

我从这个网址获取Rss: 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 "";

    }
}

3 个答案:

答案 0 :(得分:1)

如果你的描述节点包含HTML标签,它不包含任何TEXT_NODE类型的子节点,这就是它返回空的原因。

检查描述节点中子节点的类型,以了解如何处理这些节点。

修改

一种解决方案是使用getTextContent(http://docs.oracle.com/javase/1.5.0/docs/api/org/w3c/dom/Node.html#getTextContent%28%29)而不是搜索Text节点。而不是:

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

你可以简单地去:

return elem.getTextContent();

稍后,您可以使用Html.fromHtml()解析HTML:

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

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

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

EDIT2

并替换

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

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

此外,我认为SimpleAdapter期望Strings for TextViews,所以你可能需要一个ViewBinder来将Spanned放在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));
        }
    }
}

答案 1 :(得分:0)

查看此示例。它是一个简单的RSS阅读器,非常易于理解...... http://droidapp.co.uk/?p=166

答案 2 :(得分:0)

在android中显示HTML内容的最佳方式是使用Webview.So使用webview显示描述节点内的数据。它将同时显示文本和图像。这是一个示例代码...

    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);