我目前正在为Android平台制作一个rss feed阅读应用程序,它适用于一些RSS提要;但不适合其他人。特别是,它不适用于任何“天空”托管的RSS源;但我不确定为什么,每当我尝试使用天空网站的RSS源时,我都会收到上述错误消息。
像这样的RSS提要例如:http://www.skysports.com/rss/0,20514,11661,00.xml
我不确定它是否与我正在使用的XML解析有关?
有人可以指出我正确的方向指出我哪里出错了吗?
感谢。
我的Feed页面:
package com.example.directrssread;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import com.example.directrssread.Feed2.LongOperation;
import com.google.android.gms.ads.AdView;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class Feed1 extends ListFragment{
String[] URL = new String[3];
int count = 0;
String currURL = "";
View mView;
AdView adView = null;
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
//Map<Date, ArrayList> menuItems = new TreeMap<Date, ArrayList>();
Map<Date, ArrayList> sortedMap = null;
ProgressDialog progress;
//ProgressDialog.Builder builder;
// final ProgressDialog mDialog = new ProgressDialog((ViewPagerFragmentActivity)getActivity());
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_ID = "id";
static final String KEY_NAME = "name";
static final String KEY_TITLE = "title";
static final String KEY_COST = "cost";
static final String KEY_DESC = "description";
static final String KEY_LINK = "link";
static final String KEY_PUBDATE = "pubDate";
static final String KEY_PUBTIME = "pubDate";
ListView lv = null;//getListView();
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e("Feed1", "Feed1");
menuItems.removeAll(menuItems);
//lv = getListView();
mView = inflater.inflate(R.layout.feed1, container, false);
return inflater.inflate(R.layout.feed1, container, false);
}
public void onActivityCreated(Bundle savedInstanceState) {
//menuItems.removeAll(menuItems);
count = 0;
//rssRun();
lv = getListView();
new LongOperation().execute();
Log.e("Count", String.valueOf(menuItems.size()));
super.onActivityCreated(savedInstanceState);
}
public void rssRun()
{
Log.e("FEED1", "Running feed1");
boolean runSubstring = true;
URL[0] = "http://www.football365.com/premier-league/rss";
URL[1] = "http://feeds.bbci.co.uk/sport/0/football/rss.xml?edition=uk";
URL[2] = "http://www.skysports.com/rss/0,20514,11661,00.xml";
//URL[3] = "http://feeds.bbci.co.uk/sport/0/football/rss.xml?edition=uk";
for (int f= 0;f < URL.length;f++)
{
try{
//Log.e("TEst1", "TEst");
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL[f]); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
Log.e("HERE", "HERE");
//Log.e("XML", xml);
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
//Log.e("NODELIST", nl.toString());
// looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
if (doc!=null)
{
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
if (count == 0)
{
currURL = "Football365";
}
if (count == 1)
{
currURL = "BBC Sport";
}
if (count == 2)
{
//currURL = "SkySports";
}
//map.remove(map);
map.put(KEY_ID, parser.getValue(e, KEY_ID));
//Get the title of the article.
map.put(KEY_NAME, parser.getValue(e, KEY_TITLE));
//Get the description of the article.
map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
//Get the source e.g ' Football365'.
//String pubDate = parser.getValue(e, KEY_PUBDATE);
String pubDate = parser.getValue(e, KEY_PUBDATE);
//Parse the date and time from the main strings.
//Chop off the un-wanted parts.
//Bring them back together in one string.
String pubTime = pubDate.substring(17, pubDate.length());
String pubDateFormat = "";
pubTime = pubTime.substring(0, 5);
map.put(KEY_PUBDATE, pubTime);
pubDateFormat = pubDate.substring(0, 22);
pubDate = pubDate.substring(0, 16);
pubDate = pubDate + " " + pubTime;
SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm");
Date date = dateFormatter.parse(pubDateFormat);
dateFormatter = new SimpleDateFormat("dd/MM/yyyy");
//Log.e("DATE", dateFormatter.format(date));
//Calendar c = Calendar.getInstance();
//String currDate
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String currDate = sdf.format(new Date());
//Log.e("CURRENT DATE", currDate);
//System.out.println(dateFormatter.format(date));
//System.out.println(sdf2.format(date));
//Log.e("TITLE", )
map.put(KEY_TITLE, currURL + " - " + pubDate);
//Add the link.
map.put(KEY_LINK, parser.getValue(e, KEY_LINK));
//Get the publish date.
//map.put(KEY_PUBDATE, parser.getValue(e, KEY_PUBDATE));
// adding HashList to ArrayList
//10
//if (dateFormatter.format(date) == currDate)
// if (dateFormatter.format(date).substring(0, 10) == currDate.substring(0, 10))
//String input = EditTextinput.getText().toString();
//input = input.replace(" ", "");
currDate = currDate.replace(" ", "");
String rssDate = dateFormatter.format(date).replace(" ", "");
Date dt1 = dateFormatter.parse(currDate);
Date dt2 = dateFormatter.parse(rssDate);
//Log.e("TRIM CURR", currDate);
//Log.e("RSSDATE", rssDate);
//if (rssDate == currDate)
if (dt1.compareTo(dt2)==0)//== currDate)
{
menuItems.add(map);
Collections.sort(menuItems, new MapComparator(KEY_PUBTIME));
Collections.reverse(menuItems);
//sortedMap = new TreeMap<Date, ArrayList>(menuItems);
//Log.e("SAME", "THE SAME");
}
//Log.e("TRIM CURR1", currDate);
//Log.e("RSSDATE1", rssDate);
//Log.e("TEst", "TEst");
for (int q = 0;q < map.size();q++)
{
//Log.e("mene", map.get(KEY_TITLE));
}
}
}
count+=1;
}
catch(Exception e)
{
Log.e("ERROR", e.toString());
}
// Adding menuItems to ListView
final ListAdapter adapter = new SimpleAdapter(getActivity(), menuItems,
R.layout.list_item,
new String[] { KEY_NAME, KEY_DESC,KEY_LINK, KEY_TITLE }, new int[] {
R.id.name, R.id.desciption, R.id.link, R.id.source});
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setListAdapter(adapter);
//adapter.nnotifyDataSetChanged();
//stuff that updates ui
}
});
// selecting single ListView item
//TextView txt = getTextView();
//TextView firstName = (TextView) V.findViewById(R.id.textView1);
// TextView firstName = (TextView) findViewById(R.id.textView1);
//ListView lv = (ListView) findViewById(R.id.l)
//ListView lv = ((ListView) findViewbyId(R.id)
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
String cost = ((TextView) view.findViewById(R.id.cost)).getText().toString();
String link = ((TextView) view.findViewById(R.id.link)).getText().toString();
String description = ((TextView) view.findViewById(R.id.desciption)).getText().toString();
// Starting new intent
Intent in = new Intent(getActivity().getApplication(), SingleMenuItemActivity.class);
in.putExtra(KEY_NAME, name);
in.putExtra(KEY_COST, cost);
in.putExtra(KEY_DESC, description);
in.putExtra(KEY_LINK, link);
startActivity(in);
}
});
}
// mDialog.dismiss();
Log.e("RUN", "RSSRUN");
}
class LongOperation extends AsyncTask<String, Void, String> {
ProgressDialog progress1 = ProgressDialog.show(getActivity(), "dialog title",
"dialog message", true);
protected String doInBackground(String... params) {
menuItems.removeAll(menuItems);
try
{
rssRun();
}
catch(Exception e)
{
menuItems.removeAll(menuItems);
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
progress1.dismiss();
//adapter.nnotifyDataSetChanged();
//stuff that updates ui
}
});
return currURL;
}
protected void onPostExecute(String result) {
}
protected void onPreExecute() {
}
protected void onProgressUpdate(Void... values) {
}
}
class MapComparator implements Comparator<Map<String, String>>
{
private final String key;
public MapComparator(String key)
{
this.key = key;
}
public int compare(Map<String, String> first,
Map<String, String> second)
{
// TODO: Null checking, both for maps and values
String firstValue = first.get(key);
String secondValue = second.get(key);
return ((String) first.get(key)).compareTo((String) second.get(key));
}
}
}
我的XML Parser类:
package com.example.directrssread;
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.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.util.Log;
public class XMLParser {
// constructor
public XMLParser() {
}
/**
* Getting XML from URL making HTTP request
* @param url string
* */
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
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 getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
dbf.setCoalescing(true);
if (db!=null)
{
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;
}
/** Getting node value
* @param elem element
*/
public final String getElementValue2( 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 ){
if( child.getNodeType() == Node.TEXT_NODE || child.getNodeType() == Node.CDATA_SECTION_NODE ){
return child.getNodeValue();
}
}
}
}
return "";
//return elem.getTextContent();
}
/**
* Getting node value
* @param Element node
* @param key string
* */
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue2(n.item(0));
}
}
确切的错误讯息:
09-02 09:30:46.732: E/Error:(9578): Expected a quoted string (position:DOCDECL @1:50 in java.io.StringReader@4327b040)
答案 0 :(得分:0)
似乎是电话
parser.getXmlFromUrl(URL[f])
返回null,因为在出现错误的情况下,它只打印堆栈跟踪并返回null并且不会重新抛出异常。通常,不处理此错误是一个坏主意,因为在这种情况下,您可能会在其他地方发生意外行为,因为它很难解释。