Получение данных из проблемы с узлом описания в программе чтения RSS для Android

Я разрабатываю приложение для чтения RSS для Android, и у меня возникла проблема с получением содержимого 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
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);
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 по этому 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 "";

    }
}

person NovusMobile    schedule 24.04.2012    source источник


Ответы (3)


если ваш узел описания содержит теги 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, используя Html.fromHtml() :

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 )

Редактировать2

И заменить

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

с

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

Более того, я думаю, что SimpleAdapter ожидает Strings для 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));
        }
    }
}
person njzk2    schedule 24.04.2012
comment
да.. попробую. Любой пример или ссылка будут ценны. - person NovusMobile; 24.04.2012
comment
на самом деле; здесь я использую строку типа HashMap. SO может быть связано с этим. В моем коде я не получил тег Description .. где я ошибаюсь ?? Пожалуйста, направьте меня... - person NovusMobile; 25.04.2012
comment
В своем коде вы ищете child.getNodeType() == Node.TEXT_NODE. В Description такого узла нет, если описание HTML. Есть узел p. Я обновлю свой ответ, чтобы добавить потенциальных клиентов - person njzk2; 25.04.2012
comment
Спасибо за обновление ответа, но все еще сталкиваюсь с ошибкой. Метод add(HashMap‹String,Spanned›) в типе ArrayList‹HashMap‹String,Spanned›› неприменим для аргументов (HashMap‹String,String›) надеюсь, что вы даете мой отвечать . Я принимаю ваш ответ.Tx - person NovusMobile; 26.04.2012
comment
о, большое спасибо за редактирование кода. Я обнаружил, что пока я извлекаю данные, я обнаружил, что не получил код, имеющий формат HTML. так где проблема? ты меня понимаешь? - person NovusMobile; 30.04.2012

Проверьте этот пример. Это простая программа для чтения RSS, которую очень легко понять... http://droidapp.co.uk/?p=166

person Basim Sherif    schedule 24.04.2012

Лучший способ отобразить HTML-контент в Android - использовать Webview. Поэтому отображайте данные внутри узла описания с помощью 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); 
person Basim Sherif    schedule 25.04.2012
comment
Спасибо, что помогли мне дать код для отображения данных для тега html. но я структурирую до этого. Если вы запустите мой код, вы обнаружите, что в теге я нигде не получил описание tex. так что это дуэт с HashMap или чем-то еще.. - person NovusMobile; 25.04.2012
comment
k, скажи мне, чего ты хочешь добиться? Вы хотите вывести данные из узла описания? - person Basim Sherif; 25.04.2012
comment
На мой взгляд, вы должны перечислить заголовки RSS и их изображения, и когда мы нажимаем на любой заголовок, данные описания должны отображаться в веб-просмотре. Именно так я создал программу для чтения RSS, и она отлично работает. - person Basim Sherif; 25.04.2012